From 017e46212e1d67ecdafd39cc4da26b9d3d66a8ce Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:52:36 +0000 Subject: [PATCH] Deploy to GitHub pages --- 404.html | 21 +++++ CNAME | 1 + assets/app.2_UJsjMp.js | 1 + .../chunks/@localSearchIndexja-jp.CBrievQI.js | 1 + .../chunks/@localSearchIndexpt-br.DTBAfdU-.js | 1 + .../chunks/@localSearchIndexroot.C13dwPVu.js | 1 + .../@localSearchIndexzh-hans.BveK1egn.js | 1 + assets/chunks/VPLocalSearchBox.DzFCX21k.js | 7 ++ assets/chunks/framework.C9NVOr0y.js | 18 ++++ assets/chunks/theme.BQKOjM6g.js | 2 + assets/contribute_core.md.BABeyVan.js | 38 ++++++++ assets/contribute_core.md.BABeyVan.lean.js | 38 ++++++++ .../contribute_documentation.md.BYyBOKz0.js | 42 +++++++++ ...ntribute_documentation.md.BYyBOKz0.lean.js | 42 +++++++++ ...tribute_first-party-plugins.md.CpFWKmHh.js | 1 + ...te_first-party-plugins.md.CpFWKmHh.lean.js | 1 + .../contribute_github-actions.md.CA9Mkw8-.js | 1 + ...tribute_github-actions.md.CA9Mkw8-.lean.js | 1 + assets/guide_getting-started.md.C3BDv6cZ.js | 13 +++ .../guide_getting-started.md.C3BDv6cZ.lean.js | 13 +++ assets/guide_introduction.md.D7TZl5Xp.js | 1 + assets/guide_introduction.md.D7TZl5Xp.lean.js | 1 + assets/index.md.CX4EfemI.js | 1 + assets/index.md.CX4EfemI.lean.js | 1 + .../inter-italic-cyrillic-ext.r48I6akx.woff2 | Bin 0 -> 43112 bytes assets/inter-italic-cyrillic.By2_1cv3.woff2 | Bin 0 -> 31300 bytes assets/inter-italic-greek-ext.1u6EdAuj.woff2 | Bin 0 -> 17404 bytes assets/inter-italic-greek.DJ8dCoTZ.woff2 | Bin 0 -> 32564 bytes assets/inter-italic-latin-ext.CN1xVJS-.woff2 | Bin 0 -> 120840 bytes assets/inter-italic-latin.C2AdPX0b.woff2 | Bin 0 -> 74784 bytes assets/inter-italic-vietnamese.BSbpV94h.woff2 | Bin 0 -> 14884 bytes .../inter-roman-cyrillic-ext.BBPuwvHQ.woff2 | Bin 0 -> 40488 bytes assets/inter-roman-cyrillic.C5lxZ8CY.woff2 | Bin 0 -> 29164 bytes assets/inter-roman-greek-ext.CqjqNYQ-.woff2 | Bin 0 -> 16272 bytes assets/inter-roman-greek.BBVDIX6e.woff2 | Bin 0 -> 29920 bytes assets/inter-roman-latin-ext.4ZJIpNVo.woff2 | Bin 0 -> 110160 bytes assets/inter-roman-latin.Di8DUHzh.woff2 | Bin 0 -> 67792 bytes assets/inter-roman-vietnamese.BjW4sHH5.woff2 | Bin 0 -> 14072 bytes assets/ja-jp_contribute_core.md.Dl6llQ1K.js | 31 ++++++ .../ja-jp_contribute_core.md.Dl6llQ1K.lean.js | 31 ++++++ ...jp_contribute_documentation.md.DFrK7QhV.js | 42 +++++++++ ...ntribute_documentation.md.DFrK7QhV.lean.js | 42 +++++++++ ...tribute_first-party-plugins.md.C-K_bFJd.js | 1 + ...te_first-party-plugins.md.C-K_bFJd.lean.js | 1 + ...p_contribute_github-actions.md.vwGbnpnK.js | 1 + ...tribute_github-actions.md.vwGbnpnK.lean.js | 1 + ...ja-jp_guide_getting-started.md.BOrg7Hf7.js | 13 +++ ..._guide_getting-started.md.BOrg7Hf7.lean.js | 13 +++ .../ja-jp_guide_introduction.md.BiCZxaSp.js | 1 + ...-jp_guide_introduction.md.BiCZxaSp.lean.js | 1 + assets/ja-jp_index.md.Nw2yHZ3B.js | 1 + assets/ja-jp_index.md.Nw2yHZ3B.lean.js | 1 + assets/ja-jp_manage_commands.md.VPBtL-Un.js | 66 +++++++++++++ .../ja-jp_manage_commands.md.VPBtL-Un.lean.js | 66 +++++++++++++ .../ja-jp_manage_configuration.md.BoE7Ge6N.js | 9 ++ ...p_manage_configuration.md.BoE7Ge6N.lean.js | 9 ++ assets/ja-jp_manage_core.md.B1eqmXXm.js | 18 ++++ assets/ja-jp_manage_core.md.B1eqmXXm.lean.js | 18 ++++ assets/ja-jp_manage_plugins.md.Cbru-sBo.js | 11 +++ .../ja-jp_manage_plugins.md.Cbru-sBo.lean.js | 11 +++ assets/ja-jp_manage_versions.md.Dxk0G51J.js | 30 ++++++ .../ja-jp_manage_versions.md.Dxk0G51J.lean.js | 30 ++++++ ...-jp_more_community-projects.md.Drt5Trip.js | 1 + ...ore_community-projects.md.Drt5Trip.lean.js | 1 + assets/ja-jp_more_faq.md.DWV2Lkfg.js | 1 + assets/ja-jp_more_faq.md.DWV2Lkfg.lean.js | 1 + assets/ja-jp_more_thanks.md.DgZpeSyP.js | 1 + assets/ja-jp_more_thanks.md.DgZpeSyP.lean.js | 1 + assets/ja-jp_plugins_create.md.CF7Jmvco.js | 35 +++++++ .../ja-jp_plugins_create.md.CF7Jmvco.lean.js | 35 +++++++ assets/manage_commands.md.BSbw1HQ9.js | 66 +++++++++++++ assets/manage_commands.md.BSbw1HQ9.lean.js | 66 +++++++++++++ assets/manage_configuration.md.BTxM-Kga.js | 9 ++ .../manage_configuration.md.BTxM-Kga.lean.js | 9 ++ assets/manage_core.md.BUHLaRG4.js | 18 ++++ assets/manage_core.md.BUHLaRG4.lean.js | 18 ++++ assets/manage_plugins.md.BOsG6k4O.js | 11 +++ assets/manage_plugins.md.BOsG6k4O.lean.js | 11 +++ assets/manage_versions.md.CAp-N8AZ.js | 30 ++++++ assets/manage_versions.md.CAp-N8AZ.lean.js | 30 ++++++ assets/more_community-projects.md.B9Jb3CEv.js | 1 + ...ore_community-projects.md.B9Jb3CEv.lean.js | 1 + assets/more_faq.md.BjmX8xoH.js | 1 + assets/more_faq.md.BjmX8xoH.lean.js | 1 + assets/more_thanks.md.C4xnnmzS.js | 1 + assets/more_thanks.md.C4xnnmzS.lean.js | 1 + assets/plugins_create.md.Ba4Peca-.js | 35 +++++++ assets/plugins_create.md.Ba4Peca-.lean.js | 35 +++++++ assets/pt-br_contribute_core.md.BB7joZcW.js | 25 +++++ .../pt-br_contribute_core.md.BB7joZcW.lean.js | 25 +++++ ...br_contribute_documentation.md.D_CeZJ9y.js | 29 ++++++ ...ntribute_documentation.md.D_CeZJ9y.lean.js | 29 ++++++ ...tribute_first-party-plugins.md.TUKlMnR4.js | 1 + ...te_first-party-plugins.md.TUKlMnR4.lean.js | 1 + ...r_contribute_github-actions.md.BpD2TMaX.js | 1 + ...tribute_github-actions.md.BpD2TMaX.lean.js | 1 + ...pt-br_guide_getting-started.md.Bxtluukf.js | 13 +++ ..._guide_getting-started.md.Bxtluukf.lean.js | 13 +++ .../pt-br_guide_introduction.md.C231JBSG.js | 1 + ...-br_guide_introduction.md.C231JBSG.lean.js | 1 + assets/pt-br_index.md.B18T-HnP.js | 1 + assets/pt-br_index.md.B18T-HnP.lean.js | 1 + assets/pt-br_manage_commands.md.C9u0wbDc.js | 66 +++++++++++++ .../pt-br_manage_commands.md.C9u0wbDc.lean.js | 66 +++++++++++++ .../pt-br_manage_configuration.md.Bo5UByU1.js | 1 + ...r_manage_configuration.md.Bo5UByU1.lean.js | 1 + assets/pt-br_manage_core.md.CTnvZ9A5.js | 18 ++++ assets/pt-br_manage_core.md.CTnvZ9A5.lean.js | 18 ++++ assets/pt-br_manage_plugins.md.CuNF9gHf.js | 11 +++ .../pt-br_manage_plugins.md.CuNF9gHf.lean.js | 11 +++ assets/pt-br_manage_versions.md.Ctc109hL.js | 30 ++++++ .../pt-br_manage_versions.md.Ctc109hL.lean.js | 30 ++++++ ...-br_more_community-projects.md.C3m600b2.js | 1 + ...ore_community-projects.md.C3m600b2.lean.js | 1 + assets/pt-br_more_faq.md.Bch3gpm2.js | 1 + assets/pt-br_more_faq.md.Bch3gpm2.lean.js | 1 + assets/pt-br_more_thanks.md.BziNXVH9.js | 1 + assets/pt-br_more_thanks.md.BziNXVH9.lean.js | 1 + assets/pt-br_plugins_create.md.CnPY6mOB.js | 35 +++++++ .../pt-br_plugins_create.md.CnPY6mOB.lean.js | 35 +++++++ assets/style.p0L2iRKi.css | 1 + assets/zh-hans_contribute_core.md.oF4_zk5Q.js | 25 +++++ ...h-hans_contribute_core.md.oF4_zk5Q.lean.js | 25 +++++ ...ns_contribute_documentation.md.DL3_2XKG.js | 29 ++++++ ...ntribute_documentation.md.DL3_2XKG.lean.js | 29 ++++++ ...tribute_first-party-plugins.md.CaobaPwV.js | 1 + ...te_first-party-plugins.md.CaobaPwV.lean.js | 1 + ...s_contribute_github-actions.md.BMOvSElT.js | 1 + ...tribute_github-actions.md.BMOvSElT.lean.js | 1 + ...-hans_guide_getting-started.md.neLGUZQV.js | 13 +++ ..._guide_getting-started.md.neLGUZQV.lean.js | 13 +++ .../zh-hans_guide_introduction.md.4qLfdOnh.js | 1 + ...ans_guide_introduction.md.4qLfdOnh.lean.js | 1 + assets/zh-hans_index.md.DQ8VBECv.js | 1 + assets/zh-hans_index.md.DQ8VBECv.lean.js | 1 + assets/zh-hans_manage_commands.md.BJVPpY77.js | 66 +++++++++++++ ...h-hans_manage_commands.md.BJVPpY77.lean.js | 66 +++++++++++++ ...h-hans_manage_configuration.md.DckznVe9.js | 9 ++ ...s_manage_configuration.md.DckznVe9.lean.js | 9 ++ assets/zh-hans_manage_core.md._3uzcWzu.js | 18 ++++ .../zh-hans_manage_core.md._3uzcWzu.lean.js | 18 ++++ assets/zh-hans_manage_plugins.md.DY_Xuyjn.js | 11 +++ ...zh-hans_manage_plugins.md.DY_Xuyjn.lean.js | 11 +++ assets/zh-hans_manage_versions.md.BOLJYZ7r.js | 30 ++++++ ...h-hans_manage_versions.md.BOLJYZ7r.lean.js | 30 ++++++ ...ans_more_community-projects.md.yE4Odlba.js | 1 + ...ore_community-projects.md.yE4Odlba.lean.js | 1 + assets/zh-hans_more_faq.md.CgpfvsMk.js | 1 + assets/zh-hans_more_faq.md.CgpfvsMk.lean.js | 1 + assets/zh-hans_more_thanks.md.Dyz87Q2k.js | 1 + .../zh-hans_more_thanks.md.Dyz87Q2k.lean.js | 1 + assets/zh-hans_plugins_create.md.P38AmJ4g.js | 35 +++++++ ...zh-hans_plugins_create.md.P38AmJ4g.lean.js | 35 +++++++ contribute/core.html | 61 ++++++++++++ contribute/documentation.html | 65 +++++++++++++ contribute/first-party-plugins.html | 24 +++++ contribute/github-actions.html | 24 +++++ guide/getting-started.html | 36 +++++++ guide/introduction.html | 24 +++++ hashmap.json | 1 + index.html | 24 +++++ ja-jp/contribute/core.html | 54 +++++++++++ ja-jp/contribute/documentation.html | 65 +++++++++++++ ja-jp/contribute/first-party-plugins.html | 24 +++++ ja-jp/contribute/github-actions.html | 24 +++++ ja-jp/guide/getting-started.html | 36 +++++++ ja-jp/guide/introduction.html | 24 +++++ ja-jp/index.html | 24 +++++ ja-jp/manage/commands.html | 89 ++++++++++++++++++ ja-jp/manage/configuration.html | 32 +++++++ ja-jp/manage/core.html | 41 ++++++++ ja-jp/manage/plugins.html | 34 +++++++ ja-jp/manage/versions.html | 53 +++++++++++ ja-jp/more/community-projects.html | 24 +++++ ja-jp/more/faq.html | 24 +++++ ja-jp/more/thanks.html | 24 +++++ ja-jp/plugins/create.html | 82 ++++++++++++++++ manage/commands.html | 89 ++++++++++++++++++ manage/configuration.html | 32 +++++++ manage/core.html | 41 ++++++++ manage/plugins.html | 34 +++++++ manage/versions.html | 53 +++++++++++ more/community-projects.html | 24 +++++ more/faq.html | 24 +++++ more/thanks.html | 24 +++++ plugins/create.html | 82 ++++++++++++++++ pt-br/contribute/core.html | 48 ++++++++++ pt-br/contribute/documentation.html | 52 ++++++++++ pt-br/contribute/first-party-plugins.html | 24 +++++ pt-br/contribute/github-actions.html | 24 +++++ pt-br/guide/getting-started.html | 36 +++++++ pt-br/guide/introduction.html | 24 +++++ pt-br/index.html | 24 +++++ pt-br/manage/commands.html | 89 ++++++++++++++++++ pt-br/manage/configuration.html | 25 +++++ pt-br/manage/core.html | 41 ++++++++ pt-br/manage/plugins.html | 34 +++++++ pt-br/manage/versions.html | 53 +++++++++++ pt-br/more/community-projects.html | 24 +++++ pt-br/more/faq.html | 24 +++++ pt-br/more/thanks.html | 24 +++++ pt-br/plugins/create.html | 58 ++++++++++++ zh-hans/contribute/core.html | 48 ++++++++++ zh-hans/contribute/documentation.html | 52 ++++++++++ zh-hans/contribute/first-party-plugins.html | 24 +++++ zh-hans/contribute/github-actions.html | 24 +++++ zh-hans/guide/getting-started.html | 36 +++++++ zh-hans/guide/introduction.html | 24 +++++ zh-hans/index.html | 24 +++++ zh-hans/manage/commands.html | 89 ++++++++++++++++++ zh-hans/manage/configuration.html | 32 +++++++ zh-hans/manage/core.html | 41 ++++++++ zh-hans/manage/plugins.html | 34 +++++++ zh-hans/manage/versions.html | 53 +++++++++++ zh-hans/more/community-projects.html | 24 +++++ zh-hans/more/faq.html | 24 +++++ zh-hans/more/thanks.html | 24 +++++ zh-hans/plugins/create.html | 58 ++++++++++++ 218 files changed, 4604 insertions(+) create mode 100644 404.html create mode 100644 CNAME create mode 100644 assets/app.2_UJsjMp.js create mode 100644 assets/chunks/@localSearchIndexja-jp.CBrievQI.js create mode 100644 assets/chunks/@localSearchIndexpt-br.DTBAfdU-.js create mode 100644 assets/chunks/@localSearchIndexroot.C13dwPVu.js create mode 100644 assets/chunks/@localSearchIndexzh-hans.BveK1egn.js create mode 100644 assets/chunks/VPLocalSearchBox.DzFCX21k.js create mode 100644 assets/chunks/framework.C9NVOr0y.js create mode 100644 assets/chunks/theme.BQKOjM6g.js create mode 100644 assets/contribute_core.md.BABeyVan.js create mode 100644 assets/contribute_core.md.BABeyVan.lean.js create mode 100644 assets/contribute_documentation.md.BYyBOKz0.js create mode 100644 assets/contribute_documentation.md.BYyBOKz0.lean.js create mode 100644 assets/contribute_first-party-plugins.md.CpFWKmHh.js create mode 100644 assets/contribute_first-party-plugins.md.CpFWKmHh.lean.js create mode 100644 assets/contribute_github-actions.md.CA9Mkw8-.js create mode 100644 assets/contribute_github-actions.md.CA9Mkw8-.lean.js create mode 100644 assets/guide_getting-started.md.C3BDv6cZ.js create mode 100644 assets/guide_getting-started.md.C3BDv6cZ.lean.js create mode 100644 assets/guide_introduction.md.D7TZl5Xp.js create mode 100644 assets/guide_introduction.md.D7TZl5Xp.lean.js create mode 100644 assets/index.md.CX4EfemI.js create mode 100644 assets/index.md.CX4EfemI.lean.js create mode 100644 assets/inter-italic-cyrillic-ext.r48I6akx.woff2 create mode 100644 assets/inter-italic-cyrillic.By2_1cv3.woff2 create mode 100644 assets/inter-italic-greek-ext.1u6EdAuj.woff2 create mode 100644 assets/inter-italic-greek.DJ8dCoTZ.woff2 create mode 100644 assets/inter-italic-latin-ext.CN1xVJS-.woff2 create mode 100644 assets/inter-italic-latin.C2AdPX0b.woff2 create mode 100644 assets/inter-italic-vietnamese.BSbpV94h.woff2 create mode 100644 assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 create mode 100644 assets/inter-roman-cyrillic.C5lxZ8CY.woff2 create mode 100644 assets/inter-roman-greek-ext.CqjqNYQ-.woff2 create mode 100644 assets/inter-roman-greek.BBVDIX6e.woff2 create mode 100644 assets/inter-roman-latin-ext.4ZJIpNVo.woff2 create mode 100644 assets/inter-roman-latin.Di8DUHzh.woff2 create mode 100644 assets/inter-roman-vietnamese.BjW4sHH5.woff2 create mode 100644 assets/ja-jp_contribute_core.md.Dl6llQ1K.js create mode 100644 assets/ja-jp_contribute_core.md.Dl6llQ1K.lean.js create mode 100644 assets/ja-jp_contribute_documentation.md.DFrK7QhV.js create mode 100644 assets/ja-jp_contribute_documentation.md.DFrK7QhV.lean.js create mode 100644 assets/ja-jp_contribute_first-party-plugins.md.C-K_bFJd.js create mode 100644 assets/ja-jp_contribute_first-party-plugins.md.C-K_bFJd.lean.js create mode 100644 assets/ja-jp_contribute_github-actions.md.vwGbnpnK.js create mode 100644 assets/ja-jp_contribute_github-actions.md.vwGbnpnK.lean.js create mode 100644 assets/ja-jp_guide_getting-started.md.BOrg7Hf7.js create mode 100644 assets/ja-jp_guide_getting-started.md.BOrg7Hf7.lean.js create mode 100644 assets/ja-jp_guide_introduction.md.BiCZxaSp.js create mode 100644 assets/ja-jp_guide_introduction.md.BiCZxaSp.lean.js create mode 100644 assets/ja-jp_index.md.Nw2yHZ3B.js create mode 100644 assets/ja-jp_index.md.Nw2yHZ3B.lean.js create mode 100644 assets/ja-jp_manage_commands.md.VPBtL-Un.js create mode 100644 assets/ja-jp_manage_commands.md.VPBtL-Un.lean.js create mode 100644 assets/ja-jp_manage_configuration.md.BoE7Ge6N.js create mode 100644 assets/ja-jp_manage_configuration.md.BoE7Ge6N.lean.js create mode 100644 assets/ja-jp_manage_core.md.B1eqmXXm.js create mode 100644 assets/ja-jp_manage_core.md.B1eqmXXm.lean.js create mode 100644 assets/ja-jp_manage_plugins.md.Cbru-sBo.js create mode 100644 assets/ja-jp_manage_plugins.md.Cbru-sBo.lean.js create mode 100644 assets/ja-jp_manage_versions.md.Dxk0G51J.js create mode 100644 assets/ja-jp_manage_versions.md.Dxk0G51J.lean.js create mode 100644 assets/ja-jp_more_community-projects.md.Drt5Trip.js create mode 100644 assets/ja-jp_more_community-projects.md.Drt5Trip.lean.js create mode 100644 assets/ja-jp_more_faq.md.DWV2Lkfg.js create mode 100644 assets/ja-jp_more_faq.md.DWV2Lkfg.lean.js create mode 100644 assets/ja-jp_more_thanks.md.DgZpeSyP.js create mode 100644 assets/ja-jp_more_thanks.md.DgZpeSyP.lean.js create mode 100644 assets/ja-jp_plugins_create.md.CF7Jmvco.js create mode 100644 assets/ja-jp_plugins_create.md.CF7Jmvco.lean.js create mode 100644 assets/manage_commands.md.BSbw1HQ9.js create mode 100644 assets/manage_commands.md.BSbw1HQ9.lean.js create mode 100644 assets/manage_configuration.md.BTxM-Kga.js create mode 100644 assets/manage_configuration.md.BTxM-Kga.lean.js create mode 100644 assets/manage_core.md.BUHLaRG4.js create mode 100644 assets/manage_core.md.BUHLaRG4.lean.js create mode 100644 assets/manage_plugins.md.BOsG6k4O.js create mode 100644 assets/manage_plugins.md.BOsG6k4O.lean.js create mode 100644 assets/manage_versions.md.CAp-N8AZ.js create mode 100644 assets/manage_versions.md.CAp-N8AZ.lean.js create mode 100644 assets/more_community-projects.md.B9Jb3CEv.js create mode 100644 assets/more_community-projects.md.B9Jb3CEv.lean.js create mode 100644 assets/more_faq.md.BjmX8xoH.js create mode 100644 assets/more_faq.md.BjmX8xoH.lean.js create mode 100644 assets/more_thanks.md.C4xnnmzS.js create mode 100644 assets/more_thanks.md.C4xnnmzS.lean.js create mode 100644 assets/plugins_create.md.Ba4Peca-.js create mode 100644 assets/plugins_create.md.Ba4Peca-.lean.js create mode 100644 assets/pt-br_contribute_core.md.BB7joZcW.js create mode 100644 assets/pt-br_contribute_core.md.BB7joZcW.lean.js create mode 100644 assets/pt-br_contribute_documentation.md.D_CeZJ9y.js create mode 100644 assets/pt-br_contribute_documentation.md.D_CeZJ9y.lean.js create mode 100644 assets/pt-br_contribute_first-party-plugins.md.TUKlMnR4.js create mode 100644 assets/pt-br_contribute_first-party-plugins.md.TUKlMnR4.lean.js create mode 100644 assets/pt-br_contribute_github-actions.md.BpD2TMaX.js create mode 100644 assets/pt-br_contribute_github-actions.md.BpD2TMaX.lean.js create mode 100644 assets/pt-br_guide_getting-started.md.Bxtluukf.js create mode 100644 assets/pt-br_guide_getting-started.md.Bxtluukf.lean.js create mode 100644 assets/pt-br_guide_introduction.md.C231JBSG.js create mode 100644 assets/pt-br_guide_introduction.md.C231JBSG.lean.js create mode 100644 assets/pt-br_index.md.B18T-HnP.js create mode 100644 assets/pt-br_index.md.B18T-HnP.lean.js create mode 100644 assets/pt-br_manage_commands.md.C9u0wbDc.js create mode 100644 assets/pt-br_manage_commands.md.C9u0wbDc.lean.js create mode 100644 assets/pt-br_manage_configuration.md.Bo5UByU1.js create mode 100644 assets/pt-br_manage_configuration.md.Bo5UByU1.lean.js create mode 100644 assets/pt-br_manage_core.md.CTnvZ9A5.js create mode 100644 assets/pt-br_manage_core.md.CTnvZ9A5.lean.js create mode 100644 assets/pt-br_manage_plugins.md.CuNF9gHf.js create mode 100644 assets/pt-br_manage_plugins.md.CuNF9gHf.lean.js create mode 100644 assets/pt-br_manage_versions.md.Ctc109hL.js create mode 100644 assets/pt-br_manage_versions.md.Ctc109hL.lean.js create mode 100644 assets/pt-br_more_community-projects.md.C3m600b2.js create mode 100644 assets/pt-br_more_community-projects.md.C3m600b2.lean.js create mode 100644 assets/pt-br_more_faq.md.Bch3gpm2.js create mode 100644 assets/pt-br_more_faq.md.Bch3gpm2.lean.js create mode 100644 assets/pt-br_more_thanks.md.BziNXVH9.js create mode 100644 assets/pt-br_more_thanks.md.BziNXVH9.lean.js create mode 100644 assets/pt-br_plugins_create.md.CnPY6mOB.js create mode 100644 assets/pt-br_plugins_create.md.CnPY6mOB.lean.js create mode 100644 assets/style.p0L2iRKi.css create mode 100644 assets/zh-hans_contribute_core.md.oF4_zk5Q.js create mode 100644 assets/zh-hans_contribute_core.md.oF4_zk5Q.lean.js create mode 100644 assets/zh-hans_contribute_documentation.md.DL3_2XKG.js create mode 100644 assets/zh-hans_contribute_documentation.md.DL3_2XKG.lean.js create mode 100644 assets/zh-hans_contribute_first-party-plugins.md.CaobaPwV.js create mode 100644 assets/zh-hans_contribute_first-party-plugins.md.CaobaPwV.lean.js create mode 100644 assets/zh-hans_contribute_github-actions.md.BMOvSElT.js create mode 100644 assets/zh-hans_contribute_github-actions.md.BMOvSElT.lean.js create mode 100644 assets/zh-hans_guide_getting-started.md.neLGUZQV.js create mode 100644 assets/zh-hans_guide_getting-started.md.neLGUZQV.lean.js create mode 100644 assets/zh-hans_guide_introduction.md.4qLfdOnh.js create mode 100644 assets/zh-hans_guide_introduction.md.4qLfdOnh.lean.js create mode 100644 assets/zh-hans_index.md.DQ8VBECv.js create mode 100644 assets/zh-hans_index.md.DQ8VBECv.lean.js create mode 100644 assets/zh-hans_manage_commands.md.BJVPpY77.js create mode 100644 assets/zh-hans_manage_commands.md.BJVPpY77.lean.js create mode 100644 assets/zh-hans_manage_configuration.md.DckznVe9.js create mode 100644 assets/zh-hans_manage_configuration.md.DckznVe9.lean.js create mode 100644 assets/zh-hans_manage_core.md._3uzcWzu.js create mode 100644 assets/zh-hans_manage_core.md._3uzcWzu.lean.js create mode 100644 assets/zh-hans_manage_plugins.md.DY_Xuyjn.js create mode 100644 assets/zh-hans_manage_plugins.md.DY_Xuyjn.lean.js create mode 100644 assets/zh-hans_manage_versions.md.BOLJYZ7r.js create mode 100644 assets/zh-hans_manage_versions.md.BOLJYZ7r.lean.js create mode 100644 assets/zh-hans_more_community-projects.md.yE4Odlba.js create mode 100644 assets/zh-hans_more_community-projects.md.yE4Odlba.lean.js create mode 100644 assets/zh-hans_more_faq.md.CgpfvsMk.js create mode 100644 assets/zh-hans_more_faq.md.CgpfvsMk.lean.js create mode 100644 assets/zh-hans_more_thanks.md.Dyz87Q2k.js create mode 100644 assets/zh-hans_more_thanks.md.Dyz87Q2k.lean.js create mode 100644 assets/zh-hans_plugins_create.md.P38AmJ4g.js create mode 100644 assets/zh-hans_plugins_create.md.P38AmJ4g.lean.js create mode 100644 contribute/core.html create mode 100644 contribute/documentation.html create mode 100644 contribute/first-party-plugins.html create mode 100644 contribute/github-actions.html create mode 100644 guide/getting-started.html create mode 100644 guide/introduction.html create mode 100644 hashmap.json create mode 100644 index.html create mode 100644 ja-jp/contribute/core.html create mode 100644 ja-jp/contribute/documentation.html create mode 100644 ja-jp/contribute/first-party-plugins.html create mode 100644 ja-jp/contribute/github-actions.html create mode 100644 ja-jp/guide/getting-started.html create mode 100644 ja-jp/guide/introduction.html create mode 100644 ja-jp/index.html create mode 100644 ja-jp/manage/commands.html create mode 100644 ja-jp/manage/configuration.html create mode 100644 ja-jp/manage/core.html create mode 100644 ja-jp/manage/plugins.html create mode 100644 ja-jp/manage/versions.html create mode 100644 ja-jp/more/community-projects.html create mode 100644 ja-jp/more/faq.html create mode 100644 ja-jp/more/thanks.html create mode 100644 ja-jp/plugins/create.html create mode 100644 manage/commands.html create mode 100644 manage/configuration.html create mode 100644 manage/core.html create mode 100644 manage/plugins.html create mode 100644 manage/versions.html create mode 100644 more/community-projects.html create mode 100644 more/faq.html create mode 100644 more/thanks.html create mode 100644 plugins/create.html create mode 100644 pt-br/contribute/core.html create mode 100644 pt-br/contribute/documentation.html create mode 100644 pt-br/contribute/first-party-plugins.html create mode 100644 pt-br/contribute/github-actions.html create mode 100644 pt-br/guide/getting-started.html create mode 100644 pt-br/guide/introduction.html create mode 100644 pt-br/index.html create mode 100644 pt-br/manage/commands.html create mode 100644 pt-br/manage/configuration.html create mode 100644 pt-br/manage/core.html create mode 100644 pt-br/manage/plugins.html create mode 100644 pt-br/manage/versions.html create mode 100644 pt-br/more/community-projects.html create mode 100644 pt-br/more/faq.html create mode 100644 pt-br/more/thanks.html create mode 100644 pt-br/plugins/create.html create mode 100644 zh-hans/contribute/core.html create mode 100644 zh-hans/contribute/documentation.html create mode 100644 zh-hans/contribute/first-party-plugins.html create mode 100644 zh-hans/contribute/github-actions.html create mode 100644 zh-hans/guide/getting-started.html create mode 100644 zh-hans/guide/introduction.html create mode 100644 zh-hans/index.html create mode 100644 zh-hans/manage/commands.html create mode 100644 zh-hans/manage/configuration.html create mode 100644 zh-hans/manage/core.html create mode 100644 zh-hans/manage/plugins.html create mode 100644 zh-hans/manage/versions.html create mode 100644 zh-hans/more/community-projects.html create mode 100644 zh-hans/more/faq.html create mode 100644 zh-hans/more/thanks.html create mode 100644 zh-hans/plugins/create.html diff --git a/404.html b/404.html new file mode 100644 index 00000000..dc5acdf0 --- /dev/null +++ b/404.html @@ -0,0 +1,21 @@ + + +
+ + +asdf
core contribution guide.
Fork asdf
on GitHub and/or Git clone the default branch:
# clone your fork
+git clone https://github.com/<GITHUB_USER>/asdf.git
+# or clone asdf
+git clone https://github.com/asdf-vm/asdf.git
The tools for core development are in this repo's .tool-versions
. If you wish to manage with asdf
itself, add the plugins:
asdf plugin add bats https://github.com/timgluz/asdf-bats.git
+asdf plugin add shellcheck https://github.com/luizm/asdf-shellcheck.git
+asdf plugin add shfmt https://github.com/luizm/asdf-shfmt.git
Install the versions to develop asdf
with:
asdf install
It may be useful to not use asdf
to manage the tools during development on your local machine as you may need to break functionality which would then break your dev tooling. Here's the raw list of tools:
If you want to try out your changes without making change to your installed asdf
, you can set the $ASDF_DIR
variable to the path where you cloned the repository, and temporarily prepend the bin
and shims
directory of the directory to your path.
It is best to format, lint and test your code locally before you commit or push to the remote. Use the following scripts/commands:
# Lint
+./scripts/lint.bash --check
+
+# Fix & Format
+./scripts/lint.bash --fix
+
+# Test: all tests
+./scripts/test.bash
+
+# Test: for specific command
+bats test/list_commands.bash
TIP
Add tests! - Tests are required for new features and speed up review of bug fixes. Please cover new code paths before you create a Pull Request. See bats-core documentation
The following is the .gitignore
file in the asdf-vm/asdf
repository. We ignore project-specific files. Files specific to your OS, tools or workflows should be ignored in your global .gitignore
configuration, see here for more details.
/installs
+/downloads
+/plugins
+/shims
+repository
+.vagrant
+keyrings
+/tmp
.git-blame-ignore-revs
asdf
uses a .git-blame-ignore-revs
to reduce noise when running a blame. See the git blame documentation for more information.
Use the file with git blame
like so:
git blame --ignore-revs-file .git-blame-ignore-revs ./test/install_command.bats
Optionally, configure to use the file on every invocation of blame
without manually supplying it:
git config blame.ignoreRevsFile .git-blame-ignore-revs
It is possible to configure IDEs to use this file. For example, when using VSCode (with GitLens), write the following to .vscode/settings.json
:
{
+ "gitlens.advanced.blame.customArguments": [
+ "--ignore-revs-file",
+ ".git-blame-ignore-revs"
+ ]
+}
Execute tests locally with:
./scripts/test.bash
Before writing tests please read:
test/
scripts/test.bash
Bats debugging can be difficult at times. Using the TAP output with -t
flag will enable you to print outputs with the special file descriptor >&3
during test execution, simplifying debugging. As an example:
# test/some_tests.bats
+
+printf "%s\\n" "Will not be printed during bats test/some_tests.bats"
+printf "%s\\n" "Will be printed during bats -t test/some_tests.bats" >&3
This is further documented in bats-core Printing to the Terminal.
asdf
is using an automated release tool called Release Please to automatically bump the SemVer version and generate the Changelog. This information is determined by reading the commit history since the last release.
Conventional Commit messages define the format of the Pull Request Title which becomes the commit message format on the default branch. This is enforced with GitHub Action amannn/action-semantic-pull-request
.
Conventional Commit follows this format:
<type>[optional scope][optional !]: <description>
+
+<!-- examples -->
+fix: some fix
+feat: a new feature
+docs: some documentation update
+docs(website): some change for the website
+feat!: feature with breaking change
The full list of <types>
are: feat
, fix
, docs
, style
, refactor
, perf
, test
, build
, ci
, chore
, revert
.
!
: indicates a breaking changefix
: will create a new SemVer patch
feat
: will create a new SemVer minor
<type>!
: will create a new SemVer major
The Pull Request Title must follow this format.
TIP
Use Conventional Commit message format for your Pull Request Title.
The asdf-alpine and asdf-ubuntu projects are an ongoing effort to provide Dockerized images of some asdf tools. You can use these docker images as base for your development servers, or for running your production apps.
`,47)]))}const k=e(n,[["render",l]]);export{g as __pageData,k as default}; diff --git a/assets/contribute_core.md.BABeyVan.lean.js b/assets/contribute_core.md.BABeyVan.lean.js new file mode 100644 index 00000000..66d8cade --- /dev/null +++ b/assets/contribute_core.md.BABeyVan.lean.js @@ -0,0 +1,38 @@ +import{_ as e,c as a,a2 as i,o as t}from"./chunks/framework.C9NVOr0y.js";const g=JSON.parse('{"title":"asdf","description":"","frontmatter":{},"headers":[],"relativePath":"contribute/core.md","filePath":"contribute/core.md","lastUpdated":1728309110000}'),n={name:"contribute/core.md"};function l(o,s,p,r,h,d){return t(),a("div",null,s[0]||(s[0]=[i(`asdf
core contribution guide.
Fork asdf
on GitHub and/or Git clone the default branch:
# clone your fork
+git clone https://github.com/<GITHUB_USER>/asdf.git
+# or clone asdf
+git clone https://github.com/asdf-vm/asdf.git
The tools for core development are in this repo's .tool-versions
. If you wish to manage with asdf
itself, add the plugins:
asdf plugin add bats https://github.com/timgluz/asdf-bats.git
+asdf plugin add shellcheck https://github.com/luizm/asdf-shellcheck.git
+asdf plugin add shfmt https://github.com/luizm/asdf-shfmt.git
Install the versions to develop asdf
with:
asdf install
It may be useful to not use asdf
to manage the tools during development on your local machine as you may need to break functionality which would then break your dev tooling. Here's the raw list of tools:
If you want to try out your changes without making change to your installed asdf
, you can set the $ASDF_DIR
variable to the path where you cloned the repository, and temporarily prepend the bin
and shims
directory of the directory to your path.
It is best to format, lint and test your code locally before you commit or push to the remote. Use the following scripts/commands:
# Lint
+./scripts/lint.bash --check
+
+# Fix & Format
+./scripts/lint.bash --fix
+
+# Test: all tests
+./scripts/test.bash
+
+# Test: for specific command
+bats test/list_commands.bash
TIP
Add tests! - Tests are required for new features and speed up review of bug fixes. Please cover new code paths before you create a Pull Request. See bats-core documentation
The following is the .gitignore
file in the asdf-vm/asdf
repository. We ignore project-specific files. Files specific to your OS, tools or workflows should be ignored in your global .gitignore
configuration, see here for more details.
/installs
+/downloads
+/plugins
+/shims
+repository
+.vagrant
+keyrings
+/tmp
.git-blame-ignore-revs
asdf
uses a .git-blame-ignore-revs
to reduce noise when running a blame. See the git blame documentation for more information.
Use the file with git blame
like so:
git blame --ignore-revs-file .git-blame-ignore-revs ./test/install_command.bats
Optionally, configure to use the file on every invocation of blame
without manually supplying it:
git config blame.ignoreRevsFile .git-blame-ignore-revs
It is possible to configure IDEs to use this file. For example, when using VSCode (with GitLens), write the following to .vscode/settings.json
:
{
+ "gitlens.advanced.blame.customArguments": [
+ "--ignore-revs-file",
+ ".git-blame-ignore-revs"
+ ]
+}
Execute tests locally with:
./scripts/test.bash
Before writing tests please read:
test/
scripts/test.bash
Bats debugging can be difficult at times. Using the TAP output with -t
flag will enable you to print outputs with the special file descriptor >&3
during test execution, simplifying debugging. As an example:
# test/some_tests.bats
+
+printf "%s\\n" "Will not be printed during bats test/some_tests.bats"
+printf "%s\\n" "Will be printed during bats -t test/some_tests.bats" >&3
This is further documented in bats-core Printing to the Terminal.
asdf
is using an automated release tool called Release Please to automatically bump the SemVer version and generate the Changelog. This information is determined by reading the commit history since the last release.
Conventional Commit messages define the format of the Pull Request Title which becomes the commit message format on the default branch. This is enforced with GitHub Action amannn/action-semantic-pull-request
.
Conventional Commit follows this format:
<type>[optional scope][optional !]: <description>
+
+<!-- examples -->
+fix: some fix
+feat: a new feature
+docs: some documentation update
+docs(website): some change for the website
+feat!: feature with breaking change
The full list of <types>
are: feat
, fix
, docs
, style
, refactor
, perf
, test
, build
, ci
, chore
, revert
.
!
: indicates a breaking changefix
: will create a new SemVer patch
feat
: will create a new SemVer minor
<type>!
: will create a new SemVer major
The Pull Request Title must follow this format.
TIP
Use Conventional Commit message format for your Pull Request Title.
The asdf-alpine and asdf-ubuntu projects are an ongoing effort to provide Dockerized images of some asdf tools. You can use these docker images as base for your development servers, or for running your production apps.
`,47)]))}const k=e(n,[["render",l]]);export{g as __pageData,k as default}; diff --git a/assets/contribute_documentation.md.BYyBOKz0.js b/assets/contribute_documentation.md.BYyBOKz0.js new file mode 100644 index 00000000..ff60ed67 --- /dev/null +++ b/assets/contribute_documentation.md.BYyBOKz0.js @@ -0,0 +1,42 @@ +import{_ as i,c as a,a2 as e,o as n}from"./chunks/framework.C9NVOr0y.js";const c=JSON.parse('{"title":"Docs & Site","description":"","frontmatter":{},"headers":[],"relativePath":"contribute/documentation.md","filePath":"contribute/documentation.md","lastUpdated":1687069487000}'),t={name:"contribute/documentation.md"};function l(p,s,h,o,r,d){return n(),a("div",null,s[0]||(s[0]=[e(`Documentation & site contribution guide.
Fork asdf
on GitHub and/or Git clone the default branch:
# clone your fork
+git clone https://github.com/<GITHUB_USER>/asdf.git
+# or clone asdf
+git clone https://github.com/asdf-vm/asdf.git
The tools for Docs site development are managed with asdf
in the docs/.tool-versions
. Add the plugins with:
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs
Install the tool version(s) with:
asdf install
Install Node.js dependencies from docs/package.json
:
npm install
VitePress (v2) is the Static Site Generator (SSG) we use to build the asdf documentation site. It was chosen to replace Docsify.js and subsequently VuePress as we would like to support an HTML only fallback when users do not have JavaScript available or enabled. This was not possible with Docsify & VitePress quicly supplanted VuePress. Other than this, the feature-set is largely the same, with the focus on writing Markdown files with minimal configuration.
package.json
contains the scripts required for development:
To start the local development server:
npm run dev
Format the code before committing:
npm run format
asdf
is using an automated release pipeline which relies on Conventional Commits in PR titles. Detailed documentation found in the core contribution guide.
When creating a PR for documentation changes please make the PR title with the Conventional Commit type docs
in the format docs: <description>
.
Configuration of the site is contained within a few TypeScript files with JS Objects used to represent the config. They are:
docs/.vitepress/config.js
: the root config file for the site. Read the VitePress documentation for it's spec.To simplify the root config, the larger JS Objects representing the navbar and sidebar configuration have been extracted and separated by their locale. See both in:
docs/.vitepress/navbars.js
docs/.vitepress/sidebars.js
With the official documentation for these configs living in the Default Theme Reference.
VitePress has first-class support for internationalization. The root config docs/.vitepress/config.js
defines the supported locales with their URL, title in the selection dropdown menu and navbar/sidebar configs references.
The navbar/sidebar configs are captured in the aforementioned config files, separated by locale and exported individually.
The markdown content for each locale must fall under a folder with the same name as the keys for locales
in the root config. That is:
// docs/.vitepress/config.js
+export default defineConfig({
+ ...
+ locales: {
+ root: {
+ label: "English",
+ lang: "en-US",
+ themeConfig: {
+ nav: navbars.en,
+ sidebar: sidebars.en,
+ },
+ },
+ "pt-br": {
+ label: "Brazilian Portuguese",
+ lang: "pr-br",
+ themeConfig: {
+ nav: navbars.pt_br,
+ sidebar: sidebars.pt_br,
+ },
+ },
+ "zh-hans": {
+ label: "简体中文",
+ lang: "zh-hans",
+ themeConfig: {
+ nav: navbars.zh_hans,
+ sidebar: sidebars.zh_hans,
+ },
+ },
+ },
+})
/pt-BR/
will require the same set of markdown files located under docs/pt-BR/
, like so:
docs
+├─ README.md
+├─ foo.md
+├─ nested
+│ └─ README.md
+└─ pt-BR
+ ├─ README.md
+ ├─ foo.md
+ └─ nested
+ └─ README.md
The official VitePress i18n documentation goes into more detail.
`,37)]))}const g=i(t,[["render",l]]);export{c as __pageData,g as default}; diff --git a/assets/contribute_documentation.md.BYyBOKz0.lean.js b/assets/contribute_documentation.md.BYyBOKz0.lean.js new file mode 100644 index 00000000..ff60ed67 --- /dev/null +++ b/assets/contribute_documentation.md.BYyBOKz0.lean.js @@ -0,0 +1,42 @@ +import{_ as i,c as a,a2 as e,o as n}from"./chunks/framework.C9NVOr0y.js";const c=JSON.parse('{"title":"Docs & Site","description":"","frontmatter":{},"headers":[],"relativePath":"contribute/documentation.md","filePath":"contribute/documentation.md","lastUpdated":1687069487000}'),t={name:"contribute/documentation.md"};function l(p,s,h,o,r,d){return n(),a("div",null,s[0]||(s[0]=[e(`Documentation & site contribution guide.
Fork asdf
on GitHub and/or Git clone the default branch:
# clone your fork
+git clone https://github.com/<GITHUB_USER>/asdf.git
+# or clone asdf
+git clone https://github.com/asdf-vm/asdf.git
The tools for Docs site development are managed with asdf
in the docs/.tool-versions
. Add the plugins with:
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs
Install the tool version(s) with:
asdf install
Install Node.js dependencies from docs/package.json
:
npm install
VitePress (v2) is the Static Site Generator (SSG) we use to build the asdf documentation site. It was chosen to replace Docsify.js and subsequently VuePress as we would like to support an HTML only fallback when users do not have JavaScript available or enabled. This was not possible with Docsify & VitePress quicly supplanted VuePress. Other than this, the feature-set is largely the same, with the focus on writing Markdown files with minimal configuration.
package.json
contains the scripts required for development:
To start the local development server:
npm run dev
Format the code before committing:
npm run format
asdf
is using an automated release pipeline which relies on Conventional Commits in PR titles. Detailed documentation found in the core contribution guide.
When creating a PR for documentation changes please make the PR title with the Conventional Commit type docs
in the format docs: <description>
.
Configuration of the site is contained within a few TypeScript files with JS Objects used to represent the config. They are:
docs/.vitepress/config.js
: the root config file for the site. Read the VitePress documentation for it's spec.To simplify the root config, the larger JS Objects representing the navbar and sidebar configuration have been extracted and separated by their locale. See both in:
docs/.vitepress/navbars.js
docs/.vitepress/sidebars.js
With the official documentation for these configs living in the Default Theme Reference.
VitePress has first-class support for internationalization. The root config docs/.vitepress/config.js
defines the supported locales with their URL, title in the selection dropdown menu and navbar/sidebar configs references.
The navbar/sidebar configs are captured in the aforementioned config files, separated by locale and exported individually.
The markdown content for each locale must fall under a folder with the same name as the keys for locales
in the root config. That is:
// docs/.vitepress/config.js
+export default defineConfig({
+ ...
+ locales: {
+ root: {
+ label: "English",
+ lang: "en-US",
+ themeConfig: {
+ nav: navbars.en,
+ sidebar: sidebars.en,
+ },
+ },
+ "pt-br": {
+ label: "Brazilian Portuguese",
+ lang: "pr-br",
+ themeConfig: {
+ nav: navbars.pt_br,
+ sidebar: sidebars.pt_br,
+ },
+ },
+ "zh-hans": {
+ label: "简体中文",
+ lang: "zh-hans",
+ themeConfig: {
+ nav: navbars.zh_hans,
+ sidebar: sidebars.zh_hans,
+ },
+ },
+ },
+})
/pt-BR/
will require the same set of markdown files located under docs/pt-BR/
, like so:
docs
+├─ README.md
+├─ foo.md
+├─ nested
+│ └─ README.md
+└─ pt-BR
+ ├─ README.md
+ ├─ foo.md
+ └─ nested
+ └─ README.md
The official VitePress i18n documentation goes into more detail.
`,37)]))}const g=i(t,[["render",l]]);export{c as __pageData,g as default}; diff --git a/assets/contribute_first-party-plugins.md.CpFWKmHh.js b/assets/contribute_first-party-plugins.md.CpFWKmHh.js new file mode 100644 index 00000000..e1a12f33 --- /dev/null +++ b/assets/contribute_first-party-plugins.md.CpFWKmHh.js @@ -0,0 +1 @@ +import{_ as r,c as t,a2 as a,o as i}from"./chunks/framework.C9NVOr0y.js";const u=JSON.parse('{"title":"First-Party Plugins","description":"","frontmatter":{},"headers":[],"relativePath":"contribute/first-party-plugins.md","filePath":"contribute/first-party-plugins.md","lastUpdated":1627017981000}'),o={name:"contribute/first-party-plugins.md"};function s(l,e,n,d,c,f){return i(),t("div",null,e[0]||(e[0]=[a('The asdf core team has authored some plugins relevant to their daily work life. Help is always welcome in maintaining and improving these plugins. See the associated repo for each linked below:
For community plugins, see:
asdf-community
organisation: A collaborative, community-driven project for long-term maintenance of asdf
plugins.asdf-plugins
shortname repo: Short-name list used by asdf
core to lookup popular asdf
plugins.asdf-plugin
topic searchThe asdf core team has authored some plugins relevant to their daily work life. Help is always welcome in maintaining and improving these plugins. See the associated repo for each linked below:
For community plugins, see:
asdf-community
organisation: A collaborative, community-driven project for long-term maintenance of asdf
plugins.asdf-plugins
shortname repo: Short-name list used by asdf
core to lookup popular asdf
plugins.asdf-plugin
topic searchasdf
installation involves:
asdf
coreasdf
.tool-versions
config filesasdf primarily requires git
& curl
. Here is a non-exhaustive list of commands to run for your package manager (some might automatically install these tools in later steps).
OS | Package Manager | Command |
---|---|---|
linux | Aptitude | apt install curl git |
linux | DNF | dnf install curl git |
linux | Pacman | pacman -S curl git |
linux | Zypper | zypper install curl git |
macOS | Homebrew | brew install coreutils curl git |
macOS | Spack | spack install coreutils curl git |
Note
sudo
may be required depending on your system configuration.
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.1
We highly recommend using the official git
method.
Method | Command |
---|---|
Homebrew | brew install asdf |
Pacman | git clone https://aur.archlinux.org/asdf-vm.git && cd asdf-vm && makepkg -si or use your preferred AUR helper |
There are many different combinations of Shells, OSs & Installation methods all of which affect the configuration here. Expand the selection below that best matches your system.
macOS users, be sure to read the warning about path_helper
at the end of this section.
Add the following to ~/.bashrc
:
. "$HOME/.asdf/asdf.sh"
Completions must be configured by adding the following to your .bashrc
:
. "$HOME/.asdf/completions/asdf.bash"
If using macOS Catalina or newer, the default shell has changed to ZSH. Unless changing back to Bash, follow the ZSH instructions.
Add the following to ~/.bash_profile
:
. "$HOME/.asdf/asdf.sh"
Completions must be configured manually with the following entry in your .bash_profile
:
. "$HOME/.asdf/completions/asdf.bash"
Add asdf.sh
to your ~/.bashrc
with:
echo -e "\\n. \\"$(brew --prefix asdf)/libexec/asdf.sh\\"" >> ~/.bashrc
Completions will need to be configured as per Homebrew's instructions or with the following:
echo -e "\\n. \\"$(brew --prefix asdf)/etc/bash_completion.d/asdf.bash\\"" >> ~/.bashrc
If using macOS Catalina or newer, the default shell has changed to ZSH. Unless changing back to Bash, follow the ZSH instructions.
Add asdf.sh
to your ~/.bash_profile
with:
echo -e "\\n. \\"$(brew --prefix asdf)/libexec/asdf.sh\\"" >> ~/.bash_profile
Completions will need to be configured as per Homebrew's instructions or with the following:
echo -e "\\n. \\"$(brew --prefix asdf)/etc/bash_completion.d/asdf.bash\\"" >> ~/.bash_profile
Add the following to ~/.bashrc
:
. /opt/asdf-vm/asdf.sh
bash-completion
needs to be installed for the completions to work.
Add the following to ~/.config/fish/config.fish
:
source ~/.asdf/asdf.fish
Completions must be configured manually with the following command:
mkdir -p ~/.config/fish/completions; and ln -s ~/.asdf/completions/asdf.fish ~/.config/fish/completions
Add asdf.fish
to your ~/.config/fish/config.fish
with:
echo -e "\\nsource "(brew --prefix asdf)"/libexec/asdf.fish" >> ~/.config/fish/config.fish
Completions are handled by Homebrew for the Fish shell. Friendly!
Add the following to ~/.config/fish/config.fish
:
source /opt/asdf-vm/asdf.fish
Completions are automatically configured on installation by the AUR package.
Add asdf.elv
to your ~/.config/elvish/rc.elv
with:
mkdir -p ~/.config/elvish/lib; ln -s ~/.asdf/asdf.elv ~/.config/elvish/lib/asdf.elv
+echo "\\n"'use asdf _asdf; var asdf~ = $_asdf:asdf~' >> ~/.config/elvish/rc.elv
+echo "\\n"'set edit:completion:arg-completer[asdf] = $_asdf:arg-completer~' >> ~/.config/elvish/rc.elv
Completions are automatically configured.
Add asdf.elv
to your ~/.config/elvish/rc.elv
with:
mkdir -p ~/.config/elvish/lib; ln -s (brew --prefix asdf)/libexec/asdf.elv ~/.config/elvish/lib/asdf.elv
+echo "\\n"'use asdf _asdf; var asdf~ = $_asdf:asdf~' >> ~/.config/elvish/rc.elv
+echo "\\n"'set edit:completion:arg-completer[asdf] = $_asdf:arg-completer~' >> ~/.config/elvish/rc.elv
Completions are automatically configured.
Add asdf.elv
to your ~/.config/elvish/rc.elv
with:
mkdir -p ~/.config/elvish/lib; ln -s /opt/asdf-vm/asdf.elv ~/.config/elvish/lib/asdf.elv
+echo "\\n"'use asdf _asdf; var asdf~ = $_asdf:asdf~' >> ~/.config/elvish/rc.elv
+echo "\\n"'set edit:completion:arg-completer[asdf] = $_asdf:arg-completer~' >> ~/.config/elvish/rc.elv
Completions are automatically configured.
Add the following to ~/.zshrc
:
. "$HOME/.asdf/asdf.sh"
OR use a ZSH Framework plugin like asdf for oh-my-zsh which will source this script and setup completions.
Completions are configured by either a ZSH Framework asdf
plugin or by adding the following to your .zshrc
:
# append completions to fpath
+fpath=(\${ASDF_DIR}/completions $fpath)
+# initialise completions with ZSH's compinit
+autoload -Uz compinit && compinit
compinit
setup, ensure compinit
is below your sourcing of asdf.sh
compinit
setup with a ZSH Framework, ensure compinit
is below your sourcing of the frameworkWarning
If you are using a ZSH Framework the associated asdf
plugin may need to be updated to use the new ZSH completions properly via fpath
. The Oh-My-ZSH asdf plugin is yet to be updated, see ohmyzsh/ohmyzsh#8837.
Add asdf.sh
to your ~/.zshrc
with:
echo -e "\\n. $(brew --prefix asdf)/libexec/asdf.sh" >> \${ZDOTDIR:-~}/.zshrc
OR use a ZSH Framework plugin like asdf for oh-my-zsh which will source this script and setup completions.
Completions are configured by either a ZSH Framework asdf
or will need to be configured as per Homebrew's instructions. If you are using a ZSH Framework the associated plugin for asdf may need to be updated to use the new ZSH completions properly via fpath
. The Oh-My-ZSH asdf plugin is yet to be updated, see ohmyzsh/ohmyzsh#8837.
Add the following to ~/.zshrc
:
. /opt/asdf-vm/asdf.sh
Completions are placed in a ZSH friendly location, but ZSH must be configured to use the autocompletions.
Add the following to ~/.config/powershell/profile.ps1
:
. "$HOME/.asdf/asdf.ps1"
Add asdf.sh
to your ~/.config/powershell/profile.ps1
with:
echo -e "\\n. \\"$(brew --prefix asdf)/libexec/asdf.ps1\\"" >> ~/.config/powershell/profile.ps1
Add the following to ~/.config/powershell/profile.ps1
:
. /opt/asdf-vm/asdf.ps1
Add asdf.nu
to your ~/.config/nushell/config.nu
with:
"\\n$env.ASDF_DIR = ($env.HOME | path join '.asdf')\\n source " + ($env.HOME | path join '.asdf/asdf.nu') | save --append $nu.config-path
Completions are automatically configured
Add asdf.nu
to your ~/.config/nushell/config.nu
with:
"\\n$env.ASDF_DIR = (brew --prefix asdf | str trim | into string | path join 'libexec')\\n source " + (brew --prefix asdf | str trim | into string | path join 'libexec/asdf.nu') | save --append $nu.config-path
Completions are automatically configured
Add asdf.nu
to your ~/.config/nushell/config.nu
with:
"\\n$env.ASDF_DIR = '/opt/asdf-vm/'\\n source /opt/asdf-vm/asdf.nu" | save --append $nu.config-path
Completions are automatically configured.
Add the following to ~/.profile
:
export ASDF_DIR="$HOME/.asdf"
+. "$HOME/.asdf/asdf.sh"
Add asdf.sh
to your ~/.profile
with:
echo -e "\\nexport ASDF_DIR=\\"$(brew --prefix asdf)/libexec/asdf.sh\\"" >> ~/.profile
+echo -e "\\n. \\"$(brew --prefix asdf)/libexec/asdf.sh\\"" >> ~/.profile
Add the following to ~/.profile
:
export ASDF_DIR="/opt/asdf-vm"
+. /opt/asdf-vm/asdf.sh
asdf
scripts need to be sourced after you have set your $PATH
and after you have sourced your framework (oh-my-zsh etc).
WARNING
On macOS, starting a Bash or Zsh shell automatically calls a utility called path_helper
. path_helper
can rearrange items in PATH
(and MANPATH
), causing inconsistent behavior for tools that require specific ordering. To workaround this, asdf
on macOS defaults to forcily adding its PATH
-entries to the front (taking highest priority). This is controllable with the ASDF_FORCE_PREPEND
variable.
Restart your shell so that PATH
changes take effect. Opening a new terminal tab will usually do it.
This completes the installation of the asdf
core 🎉
asdf
is only useful once you install a plugin, install a tool and manage its versions. Continue the guide below to learn how to do this.
For demonstration purposes we will install & set Node.js via the asdf-nodejs
plugin.
Each plugin has dependencies so we need to check the plugin repo where they should be listed. For asdf-nodejs
they are:
OS | Dependency Installation |
---|---|
Debian | apt-get install dirmngr gpg curl gawk |
CentOS/ Rocky Linux/ AlmaLinux | yum install gnupg2 curl gawk |
macOS | brew install gpg gawk |
We should install dependencies first as some Plugins have post-install hooks.
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
Now we have a plugin for Node.js we can install a version of the tool.
We can see which versions are available with asdf list all nodejs
or a subset of versions with asdf list all nodejs 14
.
We will just install the latest
available version:
asdf install nodejs latest
Note
asdf
enforces exact versions. latest
is a helper throughout asdf
that will resolve to the actual version number at the time of execution.
asdf
performs a version lookup of a tool in all .tool-versions
files from the current working directory up to the $HOME
directory. The lookup occurs just-in-time when you execute a tool that asdf
manages.
WARNING
Without a version listed for a tool execution of the tool will error. asdf current
will show you the tool & version resolution, or absence of, from your current directory so you can observe which tools will fail to execute.
Global defaults are managed in $HOME/.tool-versions
. Set a global version with:
asdf global nodejs latest
$HOME/.tool-versions
will then look like:
nodejs 16.5.0
Some OSs already have tools installed that are managed by the system and not asdf
, python
is a common example. You need to tell asdf
to pass the management back to the system. The Versions reference section will guide you.
Local versions are defined in the $PWD/.tool-versions
file (your current working directory). Usually, this will be the Git repository for a project. When in your desired directory execute:
asdf local nodejs latest
$PWD/.tool-versions
will then look like:
nodejs 16.5.0
asdf
supports the migration from existing version files from other version managers. Eg: .ruby-version
for the case of rbenv
. This is supported on a per-plugin basis.
asdf-nodejs
supports this via both .nvmrc
and .node-version
files. To enable this, add the following to your asdf
configuration file $HOME/.asdfrc
:
legacy_version_file = yes
See the configuration reference page for more config options.
That completes the Getting Started guide for asdf
🎉 You can now manage nodejs
versions for your project. Follow similar steps for each type of tool in your project!
asdf
has many more commands to become familiar with, you can see them all by running asdf --help
or asdf
. The core of the commands are broken into three categories:
asdf
installation involves:
asdf
coreasdf
.tool-versions
config filesasdf primarily requires git
& curl
. Here is a non-exhaustive list of commands to run for your package manager (some might automatically install these tools in later steps).
OS | Package Manager | Command |
---|---|---|
linux | Aptitude | apt install curl git |
linux | DNF | dnf install curl git |
linux | Pacman | pacman -S curl git |
linux | Zypper | zypper install curl git |
macOS | Homebrew | brew install coreutils curl git |
macOS | Spack | spack install coreutils curl git |
Note
sudo
may be required depending on your system configuration.
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.1
We highly recommend using the official git
method.
Method | Command |
---|---|
Homebrew | brew install asdf |
Pacman | git clone https://aur.archlinux.org/asdf-vm.git && cd asdf-vm && makepkg -si or use your preferred AUR helper |
There are many different combinations of Shells, OSs & Installation methods all of which affect the configuration here. Expand the selection below that best matches your system.
macOS users, be sure to read the warning about path_helper
at the end of this section.
Add the following to ~/.bashrc
:
. "$HOME/.asdf/asdf.sh"
Completions must be configured by adding the following to your .bashrc
:
. "$HOME/.asdf/completions/asdf.bash"
If using macOS Catalina or newer, the default shell has changed to ZSH. Unless changing back to Bash, follow the ZSH instructions.
Add the following to ~/.bash_profile
:
. "$HOME/.asdf/asdf.sh"
Completions must be configured manually with the following entry in your .bash_profile
:
. "$HOME/.asdf/completions/asdf.bash"
Add asdf.sh
to your ~/.bashrc
with:
echo -e "\\n. \\"$(brew --prefix asdf)/libexec/asdf.sh\\"" >> ~/.bashrc
Completions will need to be configured as per Homebrew's instructions or with the following:
echo -e "\\n. \\"$(brew --prefix asdf)/etc/bash_completion.d/asdf.bash\\"" >> ~/.bashrc
If using macOS Catalina or newer, the default shell has changed to ZSH. Unless changing back to Bash, follow the ZSH instructions.
Add asdf.sh
to your ~/.bash_profile
with:
echo -e "\\n. \\"$(brew --prefix asdf)/libexec/asdf.sh\\"" >> ~/.bash_profile
Completions will need to be configured as per Homebrew's instructions or with the following:
echo -e "\\n. \\"$(brew --prefix asdf)/etc/bash_completion.d/asdf.bash\\"" >> ~/.bash_profile
Add the following to ~/.bashrc
:
. /opt/asdf-vm/asdf.sh
bash-completion
needs to be installed for the completions to work.
Add the following to ~/.config/fish/config.fish
:
source ~/.asdf/asdf.fish
Completions must be configured manually with the following command:
mkdir -p ~/.config/fish/completions; and ln -s ~/.asdf/completions/asdf.fish ~/.config/fish/completions
Add asdf.fish
to your ~/.config/fish/config.fish
with:
echo -e "\\nsource "(brew --prefix asdf)"/libexec/asdf.fish" >> ~/.config/fish/config.fish
Completions are handled by Homebrew for the Fish shell. Friendly!
Add the following to ~/.config/fish/config.fish
:
source /opt/asdf-vm/asdf.fish
Completions are automatically configured on installation by the AUR package.
Add asdf.elv
to your ~/.config/elvish/rc.elv
with:
mkdir -p ~/.config/elvish/lib; ln -s ~/.asdf/asdf.elv ~/.config/elvish/lib/asdf.elv
+echo "\\n"'use asdf _asdf; var asdf~ = $_asdf:asdf~' >> ~/.config/elvish/rc.elv
+echo "\\n"'set edit:completion:arg-completer[asdf] = $_asdf:arg-completer~' >> ~/.config/elvish/rc.elv
Completions are automatically configured.
Add asdf.elv
to your ~/.config/elvish/rc.elv
with:
mkdir -p ~/.config/elvish/lib; ln -s (brew --prefix asdf)/libexec/asdf.elv ~/.config/elvish/lib/asdf.elv
+echo "\\n"'use asdf _asdf; var asdf~ = $_asdf:asdf~' >> ~/.config/elvish/rc.elv
+echo "\\n"'set edit:completion:arg-completer[asdf] = $_asdf:arg-completer~' >> ~/.config/elvish/rc.elv
Completions are automatically configured.
Add asdf.elv
to your ~/.config/elvish/rc.elv
with:
mkdir -p ~/.config/elvish/lib; ln -s /opt/asdf-vm/asdf.elv ~/.config/elvish/lib/asdf.elv
+echo "\\n"'use asdf _asdf; var asdf~ = $_asdf:asdf~' >> ~/.config/elvish/rc.elv
+echo "\\n"'set edit:completion:arg-completer[asdf] = $_asdf:arg-completer~' >> ~/.config/elvish/rc.elv
Completions are automatically configured.
Add the following to ~/.zshrc
:
. "$HOME/.asdf/asdf.sh"
OR use a ZSH Framework plugin like asdf for oh-my-zsh which will source this script and setup completions.
Completions are configured by either a ZSH Framework asdf
plugin or by adding the following to your .zshrc
:
# append completions to fpath
+fpath=(\${ASDF_DIR}/completions $fpath)
+# initialise completions with ZSH's compinit
+autoload -Uz compinit && compinit
compinit
setup, ensure compinit
is below your sourcing of asdf.sh
compinit
setup with a ZSH Framework, ensure compinit
is below your sourcing of the frameworkWarning
If you are using a ZSH Framework the associated asdf
plugin may need to be updated to use the new ZSH completions properly via fpath
. The Oh-My-ZSH asdf plugin is yet to be updated, see ohmyzsh/ohmyzsh#8837.
Add asdf.sh
to your ~/.zshrc
with:
echo -e "\\n. $(brew --prefix asdf)/libexec/asdf.sh" >> \${ZDOTDIR:-~}/.zshrc
OR use a ZSH Framework plugin like asdf for oh-my-zsh which will source this script and setup completions.
Completions are configured by either a ZSH Framework asdf
or will need to be configured as per Homebrew's instructions. If you are using a ZSH Framework the associated plugin for asdf may need to be updated to use the new ZSH completions properly via fpath
. The Oh-My-ZSH asdf plugin is yet to be updated, see ohmyzsh/ohmyzsh#8837.
Add the following to ~/.zshrc
:
. /opt/asdf-vm/asdf.sh
Completions are placed in a ZSH friendly location, but ZSH must be configured to use the autocompletions.
Add the following to ~/.config/powershell/profile.ps1
:
. "$HOME/.asdf/asdf.ps1"
Add asdf.sh
to your ~/.config/powershell/profile.ps1
with:
echo -e "\\n. \\"$(brew --prefix asdf)/libexec/asdf.ps1\\"" >> ~/.config/powershell/profile.ps1
Add the following to ~/.config/powershell/profile.ps1
:
. /opt/asdf-vm/asdf.ps1
Add asdf.nu
to your ~/.config/nushell/config.nu
with:
"\\n$env.ASDF_DIR = ($env.HOME | path join '.asdf')\\n source " + ($env.HOME | path join '.asdf/asdf.nu') | save --append $nu.config-path
Completions are automatically configured
Add asdf.nu
to your ~/.config/nushell/config.nu
with:
"\\n$env.ASDF_DIR = (brew --prefix asdf | str trim | into string | path join 'libexec')\\n source " + (brew --prefix asdf | str trim | into string | path join 'libexec/asdf.nu') | save --append $nu.config-path
Completions are automatically configured
Add asdf.nu
to your ~/.config/nushell/config.nu
with:
"\\n$env.ASDF_DIR = '/opt/asdf-vm/'\\n source /opt/asdf-vm/asdf.nu" | save --append $nu.config-path
Completions are automatically configured.
Add the following to ~/.profile
:
export ASDF_DIR="$HOME/.asdf"
+. "$HOME/.asdf/asdf.sh"
Add asdf.sh
to your ~/.profile
with:
echo -e "\\nexport ASDF_DIR=\\"$(brew --prefix asdf)/libexec/asdf.sh\\"" >> ~/.profile
+echo -e "\\n. \\"$(brew --prefix asdf)/libexec/asdf.sh\\"" >> ~/.profile
Add the following to ~/.profile
:
export ASDF_DIR="/opt/asdf-vm"
+. /opt/asdf-vm/asdf.sh
asdf
scripts need to be sourced after you have set your $PATH
and after you have sourced your framework (oh-my-zsh etc).
WARNING
On macOS, starting a Bash or Zsh shell automatically calls a utility called path_helper
. path_helper
can rearrange items in PATH
(and MANPATH
), causing inconsistent behavior for tools that require specific ordering. To workaround this, asdf
on macOS defaults to forcily adding its PATH
-entries to the front (taking highest priority). This is controllable with the ASDF_FORCE_PREPEND
variable.
Restart your shell so that PATH
changes take effect. Opening a new terminal tab will usually do it.
This completes the installation of the asdf
core 🎉
asdf
is only useful once you install a plugin, install a tool and manage its versions. Continue the guide below to learn how to do this.
For demonstration purposes we will install & set Node.js via the asdf-nodejs
plugin.
Each plugin has dependencies so we need to check the plugin repo where they should be listed. For asdf-nodejs
they are:
OS | Dependency Installation |
---|---|
Debian | apt-get install dirmngr gpg curl gawk |
CentOS/ Rocky Linux/ AlmaLinux | yum install gnupg2 curl gawk |
macOS | brew install gpg gawk |
We should install dependencies first as some Plugins have post-install hooks.
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
Now we have a plugin for Node.js we can install a version of the tool.
We can see which versions are available with asdf list all nodejs
or a subset of versions with asdf list all nodejs 14
.
We will just install the latest
available version:
asdf install nodejs latest
Note
asdf
enforces exact versions. latest
is a helper throughout asdf
that will resolve to the actual version number at the time of execution.
asdf
performs a version lookup of a tool in all .tool-versions
files from the current working directory up to the $HOME
directory. The lookup occurs just-in-time when you execute a tool that asdf
manages.
WARNING
Without a version listed for a tool execution of the tool will error. asdf current
will show you the tool & version resolution, or absence of, from your current directory so you can observe which tools will fail to execute.
Global defaults are managed in $HOME/.tool-versions
. Set a global version with:
asdf global nodejs latest
$HOME/.tool-versions
will then look like:
nodejs 16.5.0
Some OSs already have tools installed that are managed by the system and not asdf
, python
is a common example. You need to tell asdf
to pass the management back to the system. The Versions reference section will guide you.
Local versions are defined in the $PWD/.tool-versions
file (your current working directory). Usually, this will be the Git repository for a project. When in your desired directory execute:
asdf local nodejs latest
$PWD/.tool-versions
will then look like:
nodejs 16.5.0
asdf
supports the migration from existing version files from other version managers. Eg: .ruby-version
for the case of rbenv
. This is supported on a per-plugin basis.
asdf-nodejs
supports this via both .nvmrc
and .node-version
files. To enable this, add the following to your asdf
configuration file $HOME/.asdfrc
:
legacy_version_file = yes
See the configuration reference page for more config options.
That completes the Getting Started guide for asdf
🎉 You can now manage nodejs
versions for your project. Follow similar steps for each type of tool in your project!
asdf
has many more commands to become familiar with, you can see them all by running asdf --help
or asdf
. The core of the commands are broken into three categories:
asdf
is a tool version manager. All tool version definitions are contained within one file (.tool-versions
) which you can check in to your project's Git repository to share with your team, ensuring everyone is using the exact same versions of tools.
The old way of working required multiple CLI version managers, each with their distinct API, configurations files and implementation (e.g. $PATH
manipulation, shims, environment variables, etc...). asdf
provides a single interface and configuration file to simplify development workflows, and can be extended to all tools and runtimes via a simple plugin interface.
Once asdf
core is set up with your Shell configuration, plugins are installed to manage particular tools. When a tool is installed by a plugin, the executables that are installed have shims created for each of them. When you try and run one of these executables, the shim is run instead, allowing asdf
to identify which version of the tool is set in .tool-versions
and execute that version.
Tools like nvm, n and rbenv are all written as Shell scripts which create shims for the executables installed by these tools.
asdf
is very similar and was built to compete in this space of tool/runtime version management. The differentiating factor for asdf
is its plugin system which removes the need for a manager per tool/runtime, different commands per manager and different *-version
files in your repo.
augments existing shells with a new feature that can load and unload environment variables depending on the current directory.
asdf
does not manage Environment Variables, however there is a plugin asdf-direnv
to integrate direnv behaviour with asdf
.
See direnv docs for more.
The Missing Package Manager for macOS (or Linux)
Homebrew manages your packages and their upstream dependencies. asdf
does not manage upstream dependencies, it is not a package manager, that burden is upon the user, though we try and keep the dependency list small.
See Homebrew docs for more.
Nix is a tool that takes a unique approach to package management and system configuration
NixOS aims to build truly reproducible environments by managing exact versions of packages up the entire dependency tree of each tool, something asdf
does not do. NixOS does this with its own programming language, many CLI tools and a package collection of over 60,000 packages.
Again, asdf
does not manage upstream dependencies and is not a package manager.
See NixOS docs for more.
asdf
ensures teams are using the exact same versions of tools, with support for many tools via a plugin system, and the simplicity and familiarity of being a single Shell script you include in your Shell config.
Note
asdf
is not intended to be a system package manager. It is a tool version manager. Just because you can create a plugin for any tool and manage its versions with asdf
, does not mean that is the best course of action for that specific tool.
asdf
is a tool version manager. All tool version definitions are contained within one file (.tool-versions
) which you can check in to your project's Git repository to share with your team, ensuring everyone is using the exact same versions of tools.
The old way of working required multiple CLI version managers, each with their distinct API, configurations files and implementation (e.g. $PATH
manipulation, shims, environment variables, etc...). asdf
provides a single interface and configuration file to simplify development workflows, and can be extended to all tools and runtimes via a simple plugin interface.
Once asdf
core is set up with your Shell configuration, plugins are installed to manage particular tools. When a tool is installed by a plugin, the executables that are installed have shims created for each of them. When you try and run one of these executables, the shim is run instead, allowing asdf
to identify which version of the tool is set in .tool-versions
and execute that version.
Tools like nvm, n and rbenv are all written as Shell scripts which create shims for the executables installed by these tools.
asdf
is very similar and was built to compete in this space of tool/runtime version management. The differentiating factor for asdf
is its plugin system which removes the need for a manager per tool/runtime, different commands per manager and different *-version
files in your repo.
augments existing shells with a new feature that can load and unload environment variables depending on the current directory.
asdf
does not manage Environment Variables, however there is a plugin asdf-direnv
to integrate direnv behaviour with asdf
.
See direnv docs for more.
The Missing Package Manager for macOS (or Linux)
Homebrew manages your packages and their upstream dependencies. asdf
does not manage upstream dependencies, it is not a package manager, that burden is upon the user, though we try and keep the dependency list small.
See Homebrew docs for more.
Nix is a tool that takes a unique approach to package management and system configuration
NixOS aims to build truly reproducible environments by managing exact versions of packages up the entire dependency tree of each tool, something asdf
does not do. NixOS does this with its own programming language, many CLI tools and a package collection of over 60,000 packages.
Again, asdf
does not manage upstream dependencies and is not a package manager.
See NixOS docs for more.
asdf
ensures teams are using the exact same versions of tools, with support for many tools via a plugin system, and the simplicity and familiarity of being a single Shell script you include in your Shell config.
Note
asdf
is not intended to be a system package manager. It is a tool version manager. Just because you can create a plugin for any tool and manage its versions with asdf
, does not mean that is the best course of action for that specific tool.
aJxy{j56_L zLQcd%;`&~HJsDrJW_a4>d&hA{Nt%hyNLF?&qFj~s+^=YLS&kL0B0b+-|x3)hD5eTXjF;sBks*LGK6BDNMxvx zf|hib=bz^O@z GfYh`X z_yO`CpzH1h +3#A#v=GwJw%XAHfK^=;*-mAPcLQr)8z=5K2SAKwOuZg zEIkBx`o`Ma`R<)3hruP|mFgw)`p0S_K~j+b?7%_r`0alX==Lw2eWm@}R*n6=;Qq*3 zgvu!-in6Wl*KJF!mcAwXgKW+4g1zXOC9($XS*BwO$ukGY(S;jc#uVfiB n_PL z9Gx%6j}LO$Xpo}@NZ9}=jhoPDs|l{gAK(NKBzH-rqDI;jf pO2xNouqwb3n(O_lR=g*F`__{ zCV;vqT-Ou6uDVuNcvXwB-~Z3-2Glj5Yn(!_nj(_#_qR6Q{LGqGytKz5;ul#&WWNkz zTKgGmeWFo+e>2sb&2?Mrm>^IxYKr&-V%lA%6A2YxFl+tVGMsLH*D6{~fMBy*BXBzW zBnd6Xy`0QJ1R^kvW){y9Qr3Z44`=gow#u+mI(@chHuo``2U)y8*mE)mS>~#VdGXdn zG6e#d0zsTC7=?ukXHlpu4qY?I6kst0l9>W*PL?Kvab+_;J`>7eg^E}S5tERxS~AwG zm+e(K@rsL-ShIFy1po^||78yZI0@h)fExhr19%w_05S^5qJW$OkedL;qlhwKNnQZp zu>k-}N~l~qk=?#|LGk+VKSlC0wv6T!&$U1S02lx;{MHxqAAjRkfLs#zs&_9Q9vsKU zTm6F6fkEhp`_o&GuQ5KhYq$rFe-Ojx{F6VQebG-#-anqd{l$V$Ki&B0Z*IjO(EFZ1 z9-o{(binlw?J~Ogp$#7cMgT`1)T9ahe?JB?+7B7Oy*(X)z5+2c{tbVrx(WR|D+tM^ z)tG^g@JD~EH-E}_nf(0sPa^;Pvmf;Pm;XX#@#KB%%4%!qYV`5g2J4C8i|+fT{AB-3 z+4ZYy-FD&U2A9>Q!@u1>MvfMXUDY#;&8Rs8$5&?W2XNCYBz`gOcl6f)IKfoPeaydm zqVHS%&wcjGJ6~Aizp^X;hxWC-uVp*gf1k4brR@vrW>kFIwmFm6=)MbUo Eb!c6i}u<)j0k$J^p=<&RBHpZiHcw0VT2q-9N#uT(7~ zGrJycUNI?Yc?G9vVztEZbri*lmo?2E7XcHiW=e*?zxa9FA;w3=i znFcJr%KUrV{1JPXK(jc(U#48<^T07*f;%-b<{X;LH-vxo$E~lidxtMa?8M8b0W`Xt zO=H&n*<$(g=APx8UB`0zt_y&=xoDr6Hvh)$W%Jzf5v$0B_UH8MP5}OZ?dNI+H<;hD zdIa<7a&CYd?Z2rN_a9E5?XQOhdE-A@eq(;ba)|k-#lPlX&}#mV_ITs0S$899GFukj zPxhD_i%q64dHb@W5sqxfOSg@$(o* 23U`vxO16QUj*?9OLq;$TAVqHoENWWY;1tkp~J%dh0CT6zxqA$*)mzPgO zOux8<0fX;ONzTwa)KVv$wCt3djzqe5l0d<+&i#%7_UQrc__%5=!a}eosAvF*=nB1Q zM=9t*0Q 2R++V130ZFHgCQ@|TX!^x-=4%UlMR&M&=`T)RiAqs z-n%~T(OaIl47utIZ`o*Mo?Q@~JP_RCN#xceAlGgTol;PO%V=^^6v?O9A35*yPw*s$ z+9T3)&z~h*SZ3R2F9)?aeV#;MXVzM%S&wPn+vtx@9x^PP`=pYqbGmf)?$)pJB&IQB zX;TY%U>_ LIqM-f*o6&dgx+P8EP -SA!E+0M%#!vXAi;t4q#UJ@E&?jz;rYEe&@SZ62 zWFQ`z_pLq@+piN|b@j||#cb)7d*d8?FFHSMmwtD9mKl7<{m*dde_sE2>@lVs*)sew z|1Ng)4&}4msFBij&rvg@+rrrG&@VRQpW# ;h z1-touxffRFPvh5O3&%arMHjB*pR@TQucdcrtCkC|gsW!zSF=X1{TG~9(+5sQARz}H z`X9K3U(FxvjnBXE`^UbxefjsNzql)#{LEJ$%>5Wy`%LNgpa1r8*%Rl#%Wma2g#crcxI$;zV9*hYrn~R zYv`BXVe#gh%V9PE(9gzSTzrcZ{`dwk!n~UY;R MfV9|rQM@zw74~{5b0M9=-uRaSte#Cn7<6!<{t_^eW{Biw}A7Je9?n_s| zr;mq@d;xs)q>(0qlTS(S&Oz7H#Isqj@U-d9B{2W#{)tb4U!RHHE`j`6U+Dv2$#e2& zF<|#|?><;(^T-QJKVJrazx4A<5X4{p %P`hWVdP~2UW*LFhQ<8YfnzCT%@ z@nJJ{()FJyE Iaru8Iu{v&7qRa3~v|9Uo5#>oGM)M%{yLF2EM `xmVh^KtWN87-F?HJ`@Own>TRGr-wFS-{d^;r8Je#Dw RSC%u!@kjASGY7r>~cuOLHjpIIDLb+i!xolsaoU6Kv^TOKG^Ez zh{V^~f%tK5yjXnxNBUfpNRKAX48Enqm&NH+EVuH}wKPk0`+gJ&5{jQb7Eb|YyxHk* z(&g~`6g6u7PEYJ3!e70g VC)kC|gOm%HYi 3saDJGgpl)=}tQ#^jfHw}$c)z@XgDhf@mxA9L-i4iC!P?rSb( z*8SfJaQoz4`ad3abGHUyoD~HWi1EMpZYY2Pc#l2h9$^U_aI>Hg+8{SU-x8q@Mvp3~ z$p}%B@sy~c=cL$fy<}mfuqwv`3hVODSy%8oD<%Yj?TS*$#|O+q`H^zWSXU{VyQ}4O zwd%#{^>r4Y=nW_7PyD?~?DzQS( +B` zuLtZww$}o;J24*vueo%20oW~Vnf>_y{hj_<_|xv%)or_P8O1gw4*t_WP9K?r>Ub&m zDEX-bs0C?+v NLQ_Ea`wGJ$^}pED*Bo zHmJcx?7^5YV9JC!D^{jD#3s!y!y)VIwnO{IO5a)|P4u00zSpnFLqSDRlad#eNO-uE zd86Cl3PUOs0JOWZFJSZp#H*Qe tzY@L_F znjt%f)7FgGCH%U2%r<$m;hG7%frnO4*8wsa1R<6kk1^6zWfe*_i}3Dv?Bu(drL FHw zT)rDGX}IKrO9Gy95L{yr;9x(w2D!`ps~ !(<8jH5t%Q?t84O{gvOg|31K;x-kd(A#@+df8 PTyH}M)}}V&bLzH!7GBrg8!~Y~ zUm4AEm+lc>P0o*BUt~O^hKJz7X!Kn*5vr{kflLq1;x>Qgj6ZhW-tN=?&TmiVt=2iL zn5Vr?4W-SV4=LToz+iJf;_TuYdod4_4nhAWC_xV}{rOJ+CMu4>e@*M(jGruHPu0w@ z#f@6uF(`Mnzc{lqkWV;?j0zZD2wbh$Z%8SKBOE{<)q9g_-s8qYhJwth3vLq*D+*RZ zc&z(vFu!dV!yGhrflanAzpZXuIg4<}&c0# pm>XX?~gzx#B;mpQQ4S2YDe zG`gF?7In};|K^PA+y>Vdt|q~&U)BsISZExKP^oEXvM4Gd4DhujQezi#eDm1BIX7sD z=rrENTZLJF8>Ktgwj*4Rp<}hs!EwsErUf&)gAqiG&r#7?m3K_P7uH!r1=_IgydHF| z|G}*+?!Sdy4KgCJ79BB;hjgOtcykGCimmP-m33UY;T51ou!{mDZd=5eUStQkwN>u8 z7k>)~5 OrJ%O3Btf(;fJq5NpSjWF!(~5U!fB*@#GTt@3IMAz?GY!C2 zh8>$T2NoXv5u_&uK||tlQF7?iQ*E*_aEqa0bn&3p$U9^sCTTT%Ly+l>G@GPku}|q3 zp{+V&xE7{bEf+{6 &M9&Uo+6By70&SoBbL@9rT*m^2WCB zOqXDC<9 7jJY;U(sI)d7U-$19jp7msVF zG*}bLiB!y#mIosg=95?zlV^1TcYO059wd7OmJSPxALez^VMhRmM!}Ve{9Cwi@hn-T z?;IdNyg2-kXooRZ1Ajc^VNxdr=0qmx$xgSr!R^$;L^;HO_#!E6)3@qTvLVKv#HjP= z;#mkTE6m)|HkkMrTT`sLd>uQP&X;?m^~nrb8ig9JcN70EDW6U9*4YIY_dEh)od|Yu ziHFfPGsM8}bp4LNT!iZlw#mN0r&op5Oyxt&K`t)%YxORixK&FB`7X8wneS1p&_E>A zGb5<-{;GWcmYonF9eA3$R;J43c(cOg*GS?rOn{@+W4OS;BZX7{1`6 zrd uTn}T~%x}R&| zqnv!!`6Ohx_8A#s;3euY@ji*-P{vd0;|%#Q{P_dI%7L_YPwV=!C5@IG2xsw+zng~5 z7yPvf*H6l+kYZ(jF#xcNb6z_OH+(+qO)qYwH~ihrIJXVDV8L}Vvsm57bh{m*#(p=| zLXPas48EXd(z9Q< #4r#&QR1bjf%{qfzo18RuuR{M9v#v?xUy+_u(~+VHH37euhpeod4r;)JF)*IG4~ z!)u-mUOD+MkPO|)8X8FbFeqV?k4Q!cVNHrP%US3m*vLX`5KhAL8+%0UWF%j^Sg%sA ztOK!u Bc3jABvPgA|reCyEiN%S*T*IN>l|hUsP8=_$F7o8o|cam> Cq>k)UFR7*%#(riI%_Fn3 zE~*)KPt5>4AWY+_h6H((de6;p_1|S!@<|qmsC4TG{Q@CaT6EbbSH4sqEt_pgNQ0|u z|DQTn5_Da=3SG7H*4MJ>blfnraCbyZBQzT7x2mlOD{z4>*Z|DTX4ho*@vAdSUikl` zYN(R8P6HNYaP`GaCcd^zlQ^`O(F~CulHfsv>mP<&bad)*!hox%3jbQujA R5>?DIKSgrO0$D3Iy|O3zkXqs&$JQNh=L)aZ0aTzLm9|D-EL7#4{4A&P8r9 zf525A_=?`?ur<=tD NOG>-3OtNH!EkL34plg9D#$Oz}Eq7XJ`m~I_9jNekJ z(FrWm^6E};($4Ns@goXDQZq(2I;l6ScOIU*HlI;pNJuLwX?BU^OX ARhe(4(EJ z`Jr@n59Odpwiix-?_yNGI8**pntKTT4TO|gb$-;gdSXWL9EWwLz9RTf^SQM`NoGNi z8}lMEF|yh^xs#RF?<9{eD;O+K>0l)HIxe!rg?&KZw?emeQ}Sx+Ez3x!W& daA3h&4e7 3<$pE3^KsKkij_aBHsNG1n*Gq>R;!-%qJ{VtC9s_ds>Y0pRu2G5EqH zKC*#S?T>~iN5H?-#FRC2lsfV3b7Y&vt4E(Xtg=d~cQ&+e{@((q5wYA9Aq;Rk2a3AJ zwegu<^yRL5;MulUt3k#285Q8N12c3JgK)uX>5un*`ylAnlQn>olLqq}j(_rKnIiol z+_AJ8S!&H&$4JMIJSkAa4qN&&-2Hn^TVS8_onvgW?SO{}EjLt#oZytUZb=0)aWu^@ z#pb6O5xso-a?uf^0;}^bIU>oKkjy;BIp dIr=&2 A+N~EXOWz()%BjN?JpzKhz5sJJ>HL= zw82IIPM-~TUc7h3W!&f$b)Jb=d>~JqiSAiRThB!f?X Cxz1l_%IQ-v1?C?Bp7%)F*OJ0z@yqEz+=WM=ei*ZAH zzJ8H5?>a4seuL@4^zBx9ybKd#iB%8H59d?OUdVf!acjRSr8nu%NZwVCDI3byABa}{ zPQ!S+Y2vq;JukGy$P9|PnliBrF4q(SX8Fl=~bez+M6>%^N zr--ioAQ@LNIJQQF%7?3~!WwLH!{hnJev8ks{bjfO@)p$&X2+Pnk@xMuuKlW<2K=iI z1va(s&fBa%rMtzQY#wNlJh-a0uyz8Ld>;uGQt&9jDN#F$jS5LwT>B~WFM>~vq_KIF zgCx|{gW4$Q$ntdbJSoxZa#? O4YSg-_tF@^t$KHOv;^k>PJ0#=O)@T!R@wsZ)(WBd2(?_pSTA) z(X1)I*fLG(L0W#uHXknDKU@fP7bNim(c-|whD1$X!$PA+N9~A&vNMR-GRd)^jI8!> zVm*wCNZMHxhfpm-aqE!j@K|Nj*>G??p_XJ0wW>6qh^-6MBCQ}+LssLF_E(MaIQ#zN zCp!8`UQcjWp9;AOG_GQLG5H6*it` q!0C4yK*&@_`nIi{ftfhK)L0-Zu3rj%J9nb{Z$RX$}AlN zEZh?bdvUewkDm?%TTp*|a92c~`4P^yfx;r-AuY$rxNKkHy@Nws6tN%zFX4IJ<{I|c zybWsnD}*|3lzdgM?aD_8HQ14l8(+{L*A`8QAiHdt-!H$;8A{kzW6HkjXMMuy&_Gly zmRQwbMIOI@Ef(icmiOP7}HWh{Imt{F-}Bqld@1p(6?Czj6}oiC>>Y)V0w 9l^ulm*qe5_V$JP-^y3^mg=i!lCkHR#2{U zI4yF)Fr!&|kyg-kt|emK#WC!#Y~3II+aH(#Wf~A{PR2;X;+iOoHY5igH7{d(hlLdj zvn>AJW6`Avt37$y+&*EzigvkfQ_sVvB8f4n-w)oIo1qsNsopN|-=DeHF)bb54gA`n z)J!c*PrObQm6ET?!BgbM_TU7NoICJ1T!$?B!K!=oV@-m><$3*?38lZ9PE3FH9wA$< zm5nandT2PQI`Xvjk%StlRxX4$$=gQs_2K!D3m`5;x<_|jasc-EnHsk}(lKAw*N_aV z(OzjMoI>!K#O#llK6FX-(n@At;ht>2MN|Qj&p$9$e$61`L56%jaWVY5Ef&B+J2X=~aN_{RD5*#L^^rrI2n7#nZ+4S{70oZ8q zEUyv3k{6IEITJV1hQzbvkZ!FUX+Y6~Ap$Ls&WE~E6a18Cv4e!*D+J7-Q`6Gg%~{-N zx_PuGW#TBt+tG{J4UNi+FBA?l5ZnvsvS!)CFkm8UzLCh8h2<_O`w`jYE>ZEjJyUZa z4ydrXcn2xF5Vxl=rg2L=58{AW@tNGs;UPO*lG!lR0o~l*y-$-W>JDW^EFja-+XrXz zjBxQVHPNmePDd3D$UkKQD_Qle_`H3Z#V3>kz1gLNsBL|lvI<~fsMDsVF{-9juYGAh zE? F` zg4+4{k}F=kMU8{J81vWK>#Z>XhZhA$eQHaC=cwMSqorsRfrHVWjz7%yHR3PBJI+4f zukNDRD{sAz9r%kII9E+?o*Q~@9^&SXRf}G`d$jX+vFSc$AYvo<79MzS&eUycJo_lE z^JV)IJNS(5u1%Tp&DlEDMa|XEtH+xiOQvVkP?|?$h^<_`%9IDF$ATr yM%( zJxecB8VG^pO;vmglDFN1^Te++Y3}8a7 z*@8&>4}k+er?tf}`iuz`961MVcgY=vXBgFUguhs+$+eYEZn6dL!X}9zXc%NHD$(MK z+P2cS-^=TMjFaI;LZ9x>EsY!7T2){~4TeRM`@4!3Nk%nkehW-L&_$)zGdGPQxuw4s zw*P|1Qw0o0vB0uu&z1HfBZg0>m+%>5?BcEejpPVM#}ZPr>JnW>5$P_-^z5+-76>vf z!wqC%2a4}!t2VYx&g(nZ8mfG8M1OQd>5r}}e=n6GRpKlVoM=hTL99I~yhG^isO=6% z%2Shkgm`L9!-7FdWB)li*u-l=*$4H)zkEN<@{6WFf#{=nzT2BaKvVFPQi3;gj=zf+ z9olK;rwe+dLD(S_*vwr4v5pag0QOeK{^%kr^}2t+V-Z&=KXBjMOrFJ;^zFO*{f*cG z%TI`vmA==`ub6+r49w?pBnMx>cZl?js&JqdbZm6u7+!PO+=3Hk-D`jHhBkMd;@#Hl zF8+=g{D2( d7Ntr>MvIvL`Vo! !>=)6>(KIHsWo&ikq@7K~44&+u;-l&f~J6DUdak%sYTCMT;EdXb0f@nWcKF${Xn-^*6rooHlM$oQM^vy-_(`<+Tar%46?H zlV)w|W6V-uwEqhaCRC&)vY2U5fuCyQ mTUdW+h|-W$^}MROzhQdq0vh12+2iS%ynYa_zEBHVHF0sPvRt`xc~wO|nV8-A)sl zE#SJCinFNVMQo#`06@eKR?d=$p#oInaiEdgH=rw?Aq1HC+Qpj$*v8slZ>>o|vPOgz zp{XW8crRlh76H_;ITY9Z_H2u)Sc@I5g@s*u#RNn|OtHw9?3!Td9MPArt!i)gQVVJ( zv_Q$O_>K2o$b$r0g &?G)b(5#9>WuwPJ4VykOp1XxYAX <*c6stc|{rYNNW6zCp=2N{^ zz1E3`3Z*^g3H7Q!H~p1Xs%A{hZ)KowO0}jFQq+^_dRgg0g1;D@i!RX4Z9_vS? 9PwB z-uDtWe`H1{5nO!P_-MS ^2$3&~e7! !xmhP!r~vLVpW~TjJ!I0fvLLYyo-IaST8q%YIA!0!PWii0p!L> z+t~Wm1JV)Tk52QwT8@sewl*yu1=_r0xuZa~rPgn%G*jXVEzG)2+Nx!T^w9P9&j$E& zn-#_=|BOj&bQ{RE-vs}xa$yJv&d<|3*7<}=$gU{#bn9YL5SYkmXXT7PtgA>on9@k~ zkpI6=*HtX0J!v!?8wSdebu&BuPRjt!8WhizPEV>t`1;)R3d6(nxK&rGA#2{y6!kY> zky;C oIe)N9mO0UVC1oFxr+}ZaZfibThaw%ZUY3mw;aM+oD1p$o3R$vnJ3{ zYcv@o!1(LZF#B~a_@x;L(plHvH3c{|d6G@6gWLJEqUyJQ`eo@E69nndIJz>qTP?#< z8lAD@#xh>N;oqt)G=Dnx*)G?i$zmn7_QTJauAeKDOCG{MJ)61DKjT@Jxs^R*=I5w4 z8?cbszzu?#Z?abv{|d~tyjI7m`NyUSXxx7HPv TPE)a{$IBSb-n$-*Nx6k#I0o-*|8OB!?6JOo%c6+CC>Ib6e|~(Rbjt-hDZlX z^~0`RGV7iS@*1O&(4h!paRhnZ=D~=_HrK2HcJ&&RoO~-~Fw=683l&c=T|>59o!(5t zuA>mbA8tBy@G9VT^Zo}`-i_<{^CazWq4=13 gc#=StK?%o{0T04an@rq#xBd%VY5in7@Lt|UiBmT$(o0|x1{MkKapZ$%c@B* z$N?Dhb+BsTX&G1Z)|5CgGc56RB*NAdO%rBL3@S!~gqjO~FI&UWB%1~eZV4(UL;P@Q zv`F)_P=|ln#)s_@7}7?OmP<@+j+7!=L=Q8Fp3Ld$GuxYtU!(mrXZ`_)QS;#POKQ$3 zx6jN lN@U4U+Qx0@yW zFRvyNzuEEK9WkW+l+W
9cpqY4e@b{IL0yDOmNms)K5{s;cHyXVgXYf%=Oy zyfhxujM7vzp9N8Yynw1eP2rYsZv-A`jP%lS(YivuqL3&TR4CdM?SoE0muc7Oc<4Og z*6Et)`sgO=R_gB2z0ITb4qy~9W|%(AB32t)gR{lSaB_Wt{#}K>zG!`i0oGu`aKdoK z{oGq%yyBOe+*B#1%NpNo)ap p*>AA_FWKi%>geNmFB|7{Ca>aR?9$|VzXWrCR(A3z_89Rv zU4BwITY1{7xTSupnWwgwwYS7u>b>Os(EA^K*=Lhaw2#ndm(PUH1)n!W4aS;CCUS^% z#Bt(f-#O9*=`87)p9=TW|5reNU};bhc_9QHf)5D};e^zMjD?&G`5#4*H>P+~wowWw zos|8Q>y%HSh){=6N+>t9IgA>v6}~OvpQjkPGfLCz5ygqR9(^HZb4))KOLL>$i+#V% zWn1dD_Bfk3T3l1yskrxaE-z1jDgeGWvD%I)z!@)r9ch7}Ru70V{<|^&b=G%n64MY5 z=4E1x=<_^CM7Tn@W 8bJXku7mn2Ue@yyNl5E7FbffK6SrtD$9 cw!?2UmV^#ta7{Tw%O8Oo8r>0AE5`u^xLUnxq3r zs3Qfle?B1r8uY5V?#y)ku28EPSCKVXV1osgb-{=X-@5}7z`SOJZz95>?YCk>4q;$+ z9FYL@VF0l^1|6N3gmhrLkZM$r!#G3{4Z)mk9Mfe<)nq|dA=;S57(yTm$+Qh;%-YhF z488+TO7zre!slOzcVf1)IjqF2RinSo4^$VqUDIkh82rFc-2Mdft)_*N)|L11&F}Hw zJps?JQYC!a4Y?>tXWV@^SQ`8mzRHz4GCYU&Dg_1)$u-p&%IEpFMYuTha6P`1B^$ZY z_!NvnawfFkwR_5Zti1;)Cz-g3QOcgm85RMWpNF{4?+LFWx%<^?)u2z(vPbu)ezP0A zOT%b%U}JnjaF!Rq!4spHJ*o*{f*B^5+#a$Bzc84^!0#-G$h$-I#5ByoWtfIZ?z{_3 z%gBP1^NcI!qNq=igq=5J?jeMm1Ex 7Dj3G)+q+zF?0~1@j?kc$@e4 zN6azBJ!PN==FlLq$9Rl6bfftjJXZr}rj8xc_}VbvTO)?93Fn~GX*ey9<&Bh9RBM{d zjfLk23%!1{Wzzl3>(uTCTHy~C22B#%Am~gU&vWRAZk@At5~lsiB7|VIQn8%9(9#K+ zNZ{+H8V}iQar^b&ozEobFo@pWWj534!BiyHA5WLssv96gXx29e2l_(;1L<4|v}XrG zCDTG`4 BYIxmY(Fc4 z#XE|wR2;84u2y7!)E=61vv2FNhr!9+LH|&;ZRs5p(y9YruDF1Nx@}syj)ZO4ZNx5d zzt3mw?@p|FU9|>Z!EWb!Vws(Sp&{1#z%a(PtB7%*;?cqZPb8NFRs8H~_s~6X-tX;| z4|}w1FQ1Rd!3OryegeBR3cxi>K=lLy1o$9~3fUAOjAO@%4uT-XVn~Myvc f#I< zVA3th>5wpc>D!mKWX=_;^ju5(?bS-8o-Sz~wK41z{ZWTrukRi0ZVg8=C&OI3{8&$R z`j*q-UP~**vGw)e$! !VAh(dvqBu;HP z+pdX3oKG)W|8N%mK;Dqk4}zx}Tg-SV=x4m-qx2U(8Juglzj~$iv#HlO4u!87kC>n@ zS}!JXoQUz{&T^W;1{+Y=VDmM-1H%v`BccCJ?NNX=1OFZc CC2y~*XK)a4hU-( zWK%{TfKE$(&2LK^ufSSPhJtY1;KsT9vYgHt) Vp4EkylxdMW?wk;R$HDho7A}1N!|wrqv4W6vO3Yh8OF@MMG@L z8tI6xI5ItCAYQ_vps=_7Zn7jeeiFM uV73_1_!(O z_9btIag)YTkPS#Xm@Hbp{K%w2>1IUgD4fmmycn{182Fw?fQyW~DiR!C8rgD`q%Y#r z{li`g^OAX$DPuF`(O#O%7)vwmOp&HcmE+p)a89U~#FP&p7oy8ZtmMFnA|Gjv^=OJ9 z2nx7YJ1EjFSXa82RDxEyeCA8KpiiCC2UKGnl|wWG7khA<<=_% Fz zp
C P#ej2ji< Zu#Hn)Q;+#o{-vw*bj j{d9T z*95ifAiJ!x%KH4gq2B?0;op3G7zb@F2u)xcVjO*q1e=z}=N4eGNOEJ%_&PLB({;Ya zX|#;13HrQ=Bcscykv=Cw&Dt@uxusbtMH6{dq5)`aseLbvtdeD~<95W9^_(->1c*l> zby{M{tC<^v{v2o$)N-xX46N#T^Vc>%rmOPcbj^N>$AynFh;YyhPs>BlN%|;& iDfmsJjrfvO?8&*!=y&)KF(7i0(zw6POsw(CQ`1VGgS-iM*9NT|v28;H6 zfpv>pGFC&-fygAmF=D{gCWt1GQq^B<915@X|I7E-LRT&n Wn?gx{d)5%q^dSs4tVe1o9UKNc| zMR}7=Q@+o+@l`mR6=3<*CO!I-FvDU7)>SNj7lKkG4g3x&=i)|!lteHBVG+hH)PH{J ztaoSEU89MiZN)^j$$mZ`5Pdsp5C+U@~aaH?BJ%Xs}&T!>toRzDdRBwQ8;#Zo9Fz zM)(`?_`8uKQqjOH%|r8h?n(K!$r>?K?i%~A8RQfAcEILVO`^osp;}_ndc)=*d4CzX zrF~1tQ^ZX^w&=nnaGaA}JyB-hXQ#s9B5ZADhuPjd217xG*2YBxX=0~bko2jU6_lIi zja!Iy|LB-L^|)mB$*Rlv0sBljOq0%&nP?ykJV+XF<@4P;Ajeb&M}Fo-!!>rWV4;8o zTW0%zB`=^&YwZPqnL|vy>M7Wf%B!hBS8E*jDd3-hrCqFRrrkaIzb88+I)?i$@a15p zMx&k2*>TBK@nO{w69)q1SrRwOG7>jmUwDZelpp{(lT^DL5<#^SCgF5+qBD&5EC{IY z%6br{(OAxg_Z(!0B#Rx`eTc|{V}e9*NEJDo*h}1!j3!A{LRMX}(TOsPcwfox80B7> z=+A2C!l2(5iwz~yaa-%_Mloh*-~6|(^ZZ(2v#ee<+W`?AKK* -K_aYDA&$;6N(Hv z=LZwUd~jIs8iHNc36M@F6=?T1;LXn*A#X~>{5B#MJ`ANSl8A+y$S^fpyEv4k;%XJ` z*GmDiiKQZ82t8ZpfR{~SS7j94BXSW>3F+oSck(DPG_prMW2^DRKIcps7lE jfPyX%O$3yTc0q70DF1s(nLdCz9k; zd0GCf76d*nRK93U?Z(6M;7 zx91UF%GyzkDYOZXH98ErZ}9dOVzH9u9lK9oOuk55o>Q3uC{?!KZDym50}kyI0P-s&`XD2x4{TQ9JBT^*MF#VcOz zv4$=_*2O|2DXS#hiop#@B+nibw7{PSLbKDa()jK`4PON|KlC%<#<`xSid$U2|1_OE zN&?$FlO{(GJbJj7-SlKU)Aof62S>x5M9pDWcKtZkDmYl><*3A!BtjF4(x76Hm+DDU zZSwx{5kwKM05w3$zjG4^n$XU2pT bct{gi#nF<8wbHS8 z9{kdE&-{JO4-)}7F5xlcSdw{SHz46mO^E+6gAl@XP181zOK4!o4OJ3(-Y|4kR%A0m zXxm71vp(&M%vPz@leAx&R6~R;Lj!AVwskoADboNOnF?FyB?ugdH?11-5|n3I2*tf~ zp?qJ2M>BQ0#_Vhrwzte7mG2uHMj>T(2Gtk}yIZOJxN;(?X}7cqTaxefYOVfcpn7I( z;UIdB@7-%gLsm?+q%$pLza9z)R{XY38JaI&tXY?vZFuXBPPfhxt(JOiGk+pK%Bv$T zR05q#Wh+S$^-QF1H|p7O0~#Gza&oa_U! I}-T>3w%I=VEQ3M6ct5QCK2)cat!l-6-qT_f5<2k<0{RvWIDHXI+zxU zS|bV9hR8*d xCg2Fl9SHdSe6PhB>SN$;tk6v@ ztu>OQOj_l}v|^HvvPK=q-TN<7xOB}_%STTn=lPZ%yE8E!9$t*6U1z0X%Kt0Ax!0xz zaV3YwhRt!#4>_lbrdH{cwGgqQigB|zy_Nypc>jdT{k#`DgMR8OEu^HeZLLo-V`!HR z=Sh@=e_{8iXe5gunsP{uxp0d-9~t8VV_Z03KpDL1uL#;i{x03y@#lQ-){vN#r^vN# zrN=|~_WN}&g1nz|p_G^wFuI}n@ow5Lmt$!^=32NCMXB;#aZ{dk64WS&K_;RQ?OKTj z!cvE0ORT7?t%pM;mgm~MY9P36Nix^kt#gL&o4|tD>gmc;`7VsxZ`nF?#WpV&qqv_( z?YI7%tE9$%IPGzaca9wFiwq+1mLo8JaxdJryp&=FmW{vEqa=FFKROHhnZftOkizxs z;ApE^;}fItF1b8GB$uYEbecRl@bX_8{G#LAznyv+;I >rsKNJO|Dr%*<;)uvL)Nf&yQz(4^x!qw0<%YR z!5WCIo>N*Xf3aVU`_iF5v@D*2cj(K_7bvN5i%)6aafxI1BE7lOo~CdFkyRgK)2ZT@ zB?c#0N#Q7jBS>C!``xVH&pA9a!=${6D9&u7^;leRy;wzB(v#THUD|OADO%TYm`{Br z2AG98I1e*1>tJ-!Bzv1K*X{Or(K}r|h+t??c2BV#H<;3HiF~^&LtqO5jkw%0qcWJ+ z>UCL`69nd)jWQD&9~MU;T1iJe?eBeaVu=<&Qx4xj4yVS>?MUVI@U<^oNI9=d`!~!1 zb7$P>iR3%>0+`M&jyCOP4$ME{Tl7S;T1+NaX`E0#-dO@I7bg08e`%C?!^P-ay~Wdh zO9idivqNqAz{nq6 0}mi0sN+Ex7%jXe}40~TS2rzG{e$_371~qM|#}0 z3s2 _X`HI@LHH>|y;>aaE zDP?Utj%^0r?s{*mwkZm$edOuoJJG2nS4cm8+?3N4IG45~V* s1xni9ZBea>Vp}B_? zwaY6a%c#v%W=tstQi>ZJ2_d!Sl&;b!9(ZGwo;0_n8nu>eGoy5ts;dm#g9PYIac8|^ zWviVMUC2rI&fn#m#p2qPH~Y^%nxz-9zaKudZ;HU+-=Akup{@mBP2YMG9+;URd?K7q zQv23AL94oEpUBK8$^tHfaH87o5E+vMoeCTL_@)QOD<7GY3t8;(2F2^$+g_8cN-Zsi zE+HZ5^&6*nL}aYWY-HI$>P@zD3!1i6#EaDTJPjc(*((a%gfIVvkWO&&-mFgHWjaiK zQZ}Vt WRC!0#iWcf7{B zLMbuM^FTjdooen^S8L$sW2=}PRISNK#3V}S$C?Qxsf_Ra{q0yQQb)sRoQ*LU?W&6! z@{Gn%X6x%oLn?nr;#&1xdaJ++nxR*AKxc?I7}>^9>cUU5{Qd#p|Dr46hmH)XO|vAJ zS6heYd-E75vgV^l%?-Mu`1z$+2YuU6vX|e~c^(1tA>KeJR3;R7ezD`df_rc8F89wy z=BSkBEteZFzDKZ9ZoOfGc2dw#GcIz&kf2Lr|Nh&B{AyKy #j-0>;%KtS@ z#tM{e#2{$fpT^>~ANvJ@eqhRc{f~Jy0kI0GlV|ePi!g6Bu6%3*T`!&Zt{EU|EL@-q zI$C-`>f?gzV5#P4oVnCm317fu-bp%13^uTcTS&{HN>NfwuXPy&t-8^at7F6NVCJ?N zH}q7ptWZ2#TU}9L<1(M XeK}k z2Qp&u9Cx#;9c|jzZP#&MsxL`0Iq8qN3L>-6o74Q|WbKshp6?S11{kPDJmUQA4xM!~ zOELt1A$pzKmN~^br>skFwM|=-xDLzA#*{cP4$wh?-9rPM7>96g(W2X; XWL4eL*d^PgA+|wiAAof3PTT|B=&gUW!i%K~V7SwDFpy zW&ykm<{)4E+@CjAd|^1ke^x8&eXXM=5cn?#)$Q(ygM*f9rJl%)aqoYBPC&o@Qu?;`$mx;=bQ@UQ!*q?8Kl#Q3GPRbi=rD36+2y)FUYAc_(lE0jRo(G3($HB-k)HU%~ z6$8iUY~L7X+$bsL!BQ(j&MEaFX|;uoH+py2<2mwAZ6#m$);+&xruY~Cx7X@n9FwSX zYo;)#&ctuWr235(-K*0xZm!>e(x4VX`Ua?j5|ZoD^o_74AAkm$u8Mgf-hUi95JUwB zH|dapZJ|QgE{cpZ>`~pe>MuN8-Cn^@hs G@?J8%Vu4PWSCewVp4;j=Xh0b^EInCIPNSbSoVx{Y=#_vfzS*&Ivy`8%O< zdh2x}C}n}o& jB-|4Q860kY9l^{sT{O#uZrcXD^0Oo6jqE+H+57v15Tg-m zt?e&T#JprMhdoB9dy2-Q8_p(=SuUDjBkv#G@%{ATnP*}(rEg3gDGK;i=VpuEUdr;g zvxVL8O2UR$s)ar!xqKVf{_?=vz`@|K=KDuXe^*yHY`UWLzzr`Ykb8Lz*N#rs C?j^8Ct=%=~y{EM_@1 zFgj$ftL^i>s%ky?|Fs@Hi0_ZTI93 jU>jr Q# z56BO|-4V6s4ZyFvdLPpPq)N2saNr>0;BGv&f27+s!kzJz?V?hh04HcT;mlbsdZ>=% z #$<`sZm<3OoBPuxS3}iaStdhUf@2p z3t<2O0z3#1Gq#IPoFt>ALe8-7r9VA7x%d8%G1%RHDSnyQ 4q3f z8ykF|)EbPg{&jwdbTXP* G}v`#*C(f1Mim|G|4e8wBT;MPpzEy|Fh*u&Wnd z=s=K5t6!IF(4=WHAal>LA#(8)kLe8X++iw7>Z}C>hc?DZxnv@gY)YyJX(jzYV?_Z&Sa>VGcVE}BI8zVa^6}8$5Xk%*`Fr51O z9>IZQFVK!5yKCO1)^*RjHM)OS$7qM+9Wge6H$rePkPhXwz!qb!>Hf}6_vzr14fjp` zfGwX2^k&mX`a`%R=-~@GroWy%P`fqqNL?-1@h-y|KP&S$SN gMdA=06=3>+%HpI}C0$(_+-i;f>a1!C za 8T{RbOi}49RYR+sMybWWL-DZdOv?X33B2S_lJa&2CLEFG`no_i9fK* z6wq=RgfR0PE5-w% w!e4JoxP$2T-R#EZ2+G$`o` z8bQjJ;8pGhX2U-~tyE-Rb571brvcun>m!;w6zHzfd-T8At@c}_KK!24He*Z8vG7*# zzZn!2{rxox4x8&=?l?9CW~^2}kbR9u-5MtRSzj524HL ) z=fY{nO((Z+JDqQM58i&0Yg^|G#y9uWx18g8I_#Db&x5vO>xR`f5ynZGkvK^+FpGe? zN;%_A0&AbKMhR<29BxWtr^EqgTnlk`5yMG(xn+vdIZeW$RN9J#JA)75ySKrP2nwh| z1V!l3v-GmG@D`O`Pd9pPwkyaAfX|}0(Qg1H6^f~2cZ1_ C9-!zYAbKI2{w2iIakkn?BA$O?|$)uF5p&NhAa+ z-`bK3x_zJ(rZ>~jI|6@tsNJ)6E!N>jYEdv2Q&2?9SxYCx^DWDx5a}ozQX jXALGBmG%S^k>w4`Ohb@EF>haIk1kkm8o zv+7zq{(fBmIHaAio$UehoXCmf+4+rf5{HYNXx!tIWpA7UNgibNP18CGLkC=n5F~XL z$W81MFC4cg!5gh$u53D0hNVCthP?-JuPdWL&LAA)^fyJ2mqr?%jD(9B*#G9 m=TRQpm9Mn6EL>X zOrfPjSbxH7)VM~yb6nI1zufX}2%HZsuBoD namH(!A^sE?vj926b== zUd}}CM;wTY$UzwX|G{jKmo9yncxgVrN;@lY2s8EL5hHbd`q)iel#phImM4A_eBL~! zM*wM {_Roo(_mBqUT9LJt3aq3}J3o|DgJf?}sRW3^Hg!2AQmIkhOm2qBPIyE{-4O zeKY0}@jxj|!r;6QX>3V0l4v5s7HjSxquXyp`o{-bPi9}yJ{8 g)bKar4NA2vH$}QHbLXSQ su5|hNEGFOlMNmuh@z%)p}wtN-+zYTNwPQIBENFmW1)3w^(GV z&OlA;m}Yr7RBqT~Tu|2< iR(Jwo$_(W847J>QcmktcxZTMV=q% zos$h&AJ(Z1nM?cco+Fk5vz}xBXz$Q(aU80L`RqzJ%;?~i?T=Kz;Sfy6uzLvmZvNR| z(;HOF(M9kVOxam)yJL`x{h|`zVB
z84EBnOhlu6=w0JsOp>A)O6y!mSaaO=Q)!rH8|z5N#esD2C`;5nqBbA_lW`QoxZ@!4 z!rVHn61jw!F^bA%QW6^P(#Ve}rb5MAm(42Yp L;)u2d)9wX@ zmP7%AL%&_w`gVs}W?p=*eZaygE+vmT<(O%7?O(dAkqH5<7#Gx_fJH-4q>=J7wcg9R zB{*6`@2!fC5gjwU*1jwvZ_wAD9(?rYd|q cv9k z2XloX+E&v4ywbHQbI)mJh=pA6f)#-_qq2Yb9qbC* Fp&EK_$BVefP Pj(YF5NeifT93M2}al^*@`9?VWnN z)$VDP0H%(n@Xa?<7C#3&rqX8hfKneC#+IbRvaLp~Evi~SWxKX@Z^)Kb{_rfw*(*aL z7BU{3&+5YoZ+dN#tlmhGB-WmD*Nqmm5v{d88D*TIBu*3OYprBbP_e{JOan|yG&7B& zVl24ij4&l!#yQ}4JrO=*yl&`znlyuED6Q2D;T8_^`bjasu9z7Mt}IS8i?P>bFjO$G zQYK{-6$zX4kdu;r#;7hR))u{l7!8$*UUG4CgEYwnCaH|8@GkztRXFJ`H$gEMXsn%b znc&%{!E zog}In^4%~mlM;xZK)_xENDSSb6xBd *Y~1HY?Ft5Lg*`s?sbkDl;j z7q^W26`8T9SY13QA~zm$GxHQwBJm_e6~8s|UeGR6xg4{H0v?5+qdHXDkJz(n zN7V N>%FwS>8@@Df4Xo*s?3y$qUWdgEI^L&} zG-AxQ$_dYFcU^xvAff6N^ohg2&Ns}3Q>p$#$%m# 8$CV9E(L znq*B)KQdbl6%0=-Qnp0nKYWjEjybRSseL4hvauhbsBCus 7XwOq|mBgwZ_H w8VtkE1Z8VLqUCHHZE{GL6Ve!P*MO zl=s~}({@tFB%a7a@>L(440th*ew^ q}p~v0`#GAaQX5Z1iK~|)J9)-A3>`*GAn3 R@fr5<)9V^kKJ`l%jdrQ7lyEiy+u5OH5v zk0sT7I1q_xh1znSH<6@R42<|nx7%@ BqzeM=dPrJPNa>YtVq1tdDEvB0W8ABup`{61LZYVtBBZjf4=vK>-IYWq%vaIh5E9 zuZN+OBqqVbRa*n!aT3My>>Mr=eqs8jonLNEoU~mFUBsRgSXC}EhEp+G{ya~~;i?6? zou+0Rv!aqBSYd@7R@jT?4O2NdZy=qEih-5O)a)pmX#mIFgx$ucz0UuERb%HA<4ARO zB8Ajj&K>(^Lxg%ysy8}att7JUp)>-);8kjdLFnQO-3ru`@HY|i=l;8@VrITgf5-%% zQT?HN>nz6jMW`vQOY)_`8>(8q^QxwSgGYf+cKKZ@wt~(}FIc$Twl6`cjok6%>&!dL zq6UWQGx2l@aNdOZc6{@NDh^K=)4{9Z3xFD0MG`&O+GClXjUyqXFxad6{b )pvnLkvyA&M|J6tygmIbfHWKKUv(d0?8o7tq~Ac5Q)CmrHZ$|BI|jt$SWK@h~h z$})rs&?F$&gMx%}a1Q3<9GoLd-e5Z7Gi*h9$1FIjX;}1&vL8B{X#|05Bjk95PF4YY z7yC2;BYB$+TT32~>41H0n$Uny9hrtgal5; #OIBBv8?kUV_QZd~u$XygAJ%1g$3HTfF0mlgYn(&M zlY;ZBnl#;wJ==pZZ!@+nvut?@_wkXfxrGHrYSFVxz;f|0T*u|H4XO127ZvKKt?R|h zsR}Vz3F2^Tfbl3EE>mAwZ?qDe?K-;^$B|Va%u7T&YPUOCea1UR(j>Z$h6L23DWCE7 ztY*u3s$|BXaRUY3C&?W}1%HcrSwL-3W(5JY0j^iXJNgx81bj((+%cUc`cF4VSK?3a*ei3GJ+7E#1 zmpf-eFrj zwbv(q9CQI}Q3nZ|x)pFMFpb^r8CxS%mEXNar8w|?E&HqBnQ702VL7HMvgFEmZAhPL z%o8sk);LTj4yRL*z!Vd^RV(ufO~|T@V{<%6L3QF2wQnTA6jhAER8-Mk;@)?%IB;we z;xfV{aFf)98Ok8OcTFc!Q(*Qwlf8`bIdL! M6oysLwy1OHP8I(qb>=_U|5 z+1NRG``dAB1G%GjP4&EoMCuQ&@AH~CE}6#Kw{1=4*nKC-`B&@hEt}SQC`2*-r)1+u zWFap~MSz+^ea{8KVS>{MY2uk~Q!tSlHy;CVwl;=ExB^Yhh~p-MmZmj}Y*>FUl#o@( z&o1W2MTr~K$Jp5*OHn?R&>3urxVljqnapaoE_SySH97AI%Q!w9Nk8=GSmm;&12H^O z%A~Q|l%@w4dTb#D9WfN3BVds%5;cqCjKI8Qb=|0{EfGG#Fu};a5>+OseYIlObX#xv z{`S!Kl60-8mceiEAz_#}mik)Jjg<9$M6N-&JcTor1?y|$KdmCQN`BLJTm@!;Ckdk% zyj}f%M9@G`vCa0>#>;QxWm(CZz!^l$xO*7NJo7&F1~D$WWJ1vtLXgL(6@xS+l#+bv zFa!|@`x=%n2qJq@9tKe7s|X<-t;-=_CgXI71vI5fX(xl7t~xq-hB~VJkUW;`dF@mq z>h!aLF0?M}m}3L{v{|+j&ZCck*FV>^?^CtO70WA_Ee-rzTmEsbO^S!SH<-1HWm{yu z4XA7*Lgy{>9S17s;9$@MTe@Si3c{+#b!FT|R7WJu6vq$*JbWzMMq?v{p|33Ivun&d z2>=MML)6WFUb-D|QUe{dS%fu>%)NkNDl}D##Ix&7mWh-e13(rRdEcA*7NtCJSO7D@ z8E<3D+ikv(fL7A^O+LHM0)vZ9?a7VyDio?-yv;+Zhpitmbm6zb`AG3BqU{^mQmqiq z%1`cxFE?r8>j^R1f=ZJcjZK1U!5Jz`=G}6gM%XhRsVPU*l0@4Dr(ZX*z`2yyQox0F zS|{qKIvf* M{tP-;M!Bq0v8}qW1wD}1v%VR>>2|zPdyBJOsxydX{Vq- zjxwrEfipb}aNq(97Z|X4$J@{{Yv5VIqO#M2rl! +m?y94#o0u=1|!|EhBi1^ZMK!L(fe;jfM2v;kR(yYEp|J4 zB$_$%Xh9zB$RY12CnS4(y66SRWEupf1w$6yfWtKe!?q%yl?iE+t>3s7`%pgP4a5^3 zUoi1Tx92JgV=>cD+-tSj;lmY1YjQrj-c{kke>@ot7aNAFvJ0J;rf9I2=5z_iNDca? zUR!79(;JMvcMsFx_i+uxD#T#@=lx{}BWD6|!VNf!$^&d6@}LCAiaft@E&f77G(?Va zvnUdxTk&&B2}c;KaQ~}>&2B38Fnkz{Y{zU~@x*G7*bOxwaJ`1Ye?4LlK_@0-Ji5^S zA>uttvPi>{4$~+kP}U9N7(GR9^;pgIf+zxk(50lEcIAjMs&K|I-Oj6Z45KrQ4{raM z?hiZl+TlUBb71i7Zl@^wlznFaGn-!md8uZS_4@be>9YnqY|m8G%laa~mi(x-v&bU` zb2|lt@w1;gGqepd$Bc-B|J_Z`)Ad@Uy4QqmlVx@{GlQ9YQxZ(A`!BCuCD8KT^S2tL zSQ+6Y#KWNpFggNG#c&nv=bm;`g#DZ*9x;-~bSzAscG7qg%25o^1qO$OG^xPQwz%i! z1=a0i9Zm}YKIk*$)bArX6P}Nzbtevcsy$j-LZM|YK<2R4NmIoT)`bBDobc?@H90*V zPvolhS%*$-@j}&PXbq*p;f@MEA3>FeBJ+>(U^E+}ppV@K$(a^C?q-bd1-rje(HQs@ zmzB7NfZo#sE+c{H%ABL 2mx)!ghx~5w;f^fTu`edWd`WeP|VHy!KGl2_za}}Q7 zujwy3%-(aHMfV>_^y{S$V_+$0L=xF8ANK#>*H&c9UyjF;3u!z4wav7y;pWu0b3)Q1 zwDU}){82xbcI^}RX3!Q+v?`qbOH*(z9P{DP9`_TgMv04YmL^dg1%XdU;JQX-Nsglo z`^y-E$mLClvF=RfC_+%>c~KTx5lUH_^!kXS(x1m%3iFd$IYP<} d%j0`#!kU}^TkWj*>cU_({#oHguY|%0u8iq3r(z5*| zCH;vMb`(=G2hddvG+fmO{`U^8LesA8><+dDzN9hFJtlbe-HL)}nE%0$o|N?BChKiI zw6vt2NgWAnoy|hUuNQ?F@+T|Wez|SN*k(&T9iqUsVeVmhki1R7V;*Acj%#L!4fL!w z>*5(-rdg37u!E2X5IN>J4W`1h2(2u@V-~98{-$I{19NXC{H=ImijYTeUf3t!3J1dD zXTeIW!mM*fz)^XC9PJ4W4%Y(Vjc7!|6I+O3rTYjIg8e{|9X1k8S6Fi$l4jYVn1Pg9 zCU`0ggQ1X1Vd&`O4|0XX4-dAiWamWDOO%uZj!P`%GuL#l#GEQ9wT0j7bWy60rmBsn zp6Ph@& G~vJsUl zE{W$Ub49~$kJs;}SoS6OM3SPNV;>+JwbZ)b$o(Z^%Zbb3#m}67i75?8u5*oH9I` zES4MxFY{eK{V3QQu+*M `Y({JpsnRI6@N89% zNbI)S=r&P8G~0)fp9W!d``CiKLER^c&G+BmW#M(ysb=RlJJz_;gLA#Uy#rtI&vkn; zu@qu6p{#xO=Rn1;ErieNtk^V;+l9jDJs}qy3KP3ut<#n{E?UJZ0k*w^+_`^#w^JLs z`Aq(dJ_&O7$@ q*?wGvW_#3&JR zR<`tzU@WzidlZn+jEEJp{pt`&vRZC)#+6_&$%L7 JR(To8kbNI1^Q2J`Gmk *sIi<% ?;hIOQ@>7dJ!>zy_oW{q~5b6`E zQ?dzCo#cdcC@#)k&R*9Pxc^FZ!!=U(%-ialCOUSmvO?4+7C73*msu8cA*8p|ZHFS) z^L-b!EIHw`0^Kf}I>h&oX>=_#T8a=wv=JjZ)^oeP#C(+FH5FYAZ`~GewWOhqGZsa0 zN>Fpdi-KFU)z0rd(%A*!+VTxPd7}~vZa7%cqb!bb7H@CR!5P`-1G|3y ^J%a1!qX(rxQf~mHR#z=tej(cJaTyJsf&iC&0o}d!s)JoN z%j |gL* z( 6T4km#*rO!i>Xz5Yk@QHRvQ%~fF3WW zI%`~fRzkJU36B4XTgLFZ7%D$rC&oFKBoM>P#fks=4Xw&CHF^C=C&$^QPo2ND-)c$H zvKVo;KI##=d(#7l*3*@p I%{yw+ zv9l|N)6 rU1?FNH2t}TtLA+|Rf1UUCnbbvU8V^A~JazKfmwATIYBZu;e&F;~4q|GeAevmA zEKlXZThT%O`k6zTn(b~;d#V})iY4A9fft0sSd^P|K(UGHf9_2;LxS6ZiW$dbQFK}Z z!zvqqu5mIG(ic)-o4}H}vjk&^Ma!_ax_flA*%;N!NRmFfN{&OOjm9TH^oNnoD#4zW z#F`op+=Kyr%1CNxyhL`ooAg;4B}2fown~FPebf8FJ|#pHm0^h0DnHBx_6F_AwYk*T z7D{WuFxMH1`~9Qd2Hy@EzeV|^SmyJ$3I|O$hr6WfcD84vo+DTzR3~xj3RUGqLu|tC zfWTB2wUdu*z3LIZh=K~wylmUD>>Bv%p-{9b4XJ4ZgfmqSY@!P4FWSwZ-vQCepUhkN z*!I d0Q%qjFgx476?9EqTpKJa{hO3^6Cm>c&i*3`Kj6H6Dyd1?0QH) zFQQ63FUvigW$8xPD>AU8W}HOjde8p2tG$^7At)p^ y&Pl4yc)S?lC@0l1x(>ts$;u85mIQ >>#MPg9F3FYMzh12ARoM1$?T~YdyJ8GgDiiu z-ar1-ME#2?A3MCSp8V%G-C(y#vgvAsv=ST9PD|c$qZeKU=+rrGkAAdLyr&9TKYgd8 zx=Lbn0^hH+(dw1!_URiu<#SH*K4E>I9zYK{B#Xi^ZL<{QL!vO-<0D$XWmc>M)rryp zOtO_e=AiZf^h0NhiQz!iF-#3yfM>7>m*Rrea)-#ai0@&KR1#B8pyEhVhd!9ILnmVg zwD%+gS~j$8OlUM{uyHUL2BsKd8%K>yVhmw;;Ebzh(u{>r#1MvnKsOj`LT7!y`cXMy zlz{(gykGkX3k%1AHU2LtZCq6QN$-qdzkwM^mAAN>Inn@yxio*9xjzyMQMLnK5WtZ= zVR*rTY#3Iq`#`j8wT`(X-&NeUT~>5%I7Wr$;1-(RJQeP4M #u$qRENx+g)|x5> z#@dK5Z=k%78HQktQc@vf499KuyeN?r!?G03ay-itjwFdwo*;M*CpelUof%1zyd;Z) zz>owsF9 7Xe;@Xa#ob|oc2eYZ_L1< zK}P&Ofwev>DQ@=Sm==m%Q{XjXqB>7KBHa7``aq;Oc^%x#2>S)LChea_=28$-t?IUp zu0*=}G%UK9hI3+Oz@k$(7bi(ukKcr#Ih4lnB^GK9EJ_YGFEX39NZvnBKKT6GLcUeB z8N=#Gr6!9TE5P1;++Q}zc);Vv@jFj J%*wgEBA%Yp@? -?f+REs=sJ z0kshwZ(lh+A0HMT3#F=>YeR94mg>5 fRsRo5y%_dow}{@b5$VfQ8Wk&2k#s*zj!`(x%sl2 zuA(2xC4Z8Eh?AXVD0kuKA!u$@p0Bdda)GE`A7rlgH6{14HZAWK-yT?M;dK6e;Y`en zu5Y~@4|nTb;X-Y_KRw><$c;a_o{Gww;hTdwNj%*!+qXe)R&n%=dlXd|90+ydYB(W- zR*QCSO1Aw;y!J^}9`%c@bDN`H;}BJKluZOv bB;S?F+OH?sVT8#LO$>hE zkdutm+VM;s+0EH>yCn -NgYW!xezGN}~aXqo6rB(NK zyS;iqK-FIA$t20DdI{}cVAV|U2N8AGceD<0PFoJzm&V+arNajkK}Mb9j=9bPMq)0m z$4HFyRZpmGS Cxj4S#@N!GlCI z*lEs>(rWs#Bs;b3A;4;n|IgV6z^Ta3#uSftRS>LZ?YuT05ewve=zH20cBe06`_Dyb z5=G&l#jzIN6!}akLE3(i#nfi>4S@!rdAL||Q*KaVg+T4dq$o9=HOVAOD {ZRsB^z40rYS 51m)Q8`1(5~;W z6-F$=&%Z~=_}l+gV>FeL4eKNxba-^|RQ5`!k&IJzNRp(Br^9^GSUt6vq#MaC7c4m- zgkq;5BqY(n!J|)D&Ws9V`S&J(SqdZQ&I`MkcWR#%cF1cg=2!8%!&3(?gE=uY-Km?g zYEq%!rovif?5UAK1Z|Y>rg2izAWYIUA8;X9TjX&_X<4MGc4cWM%ZqueRW-|L_Mcn? zv@=Hg*q8*CY &D)tt-=3raNWs z<)tCC;_KauJ{il9gfN1xbKGzO#|QK_ueT`JP7>{d9|*d`^Uw|Z)w+#iySfL1b|&A_ z9Zk=#$sC|IeWw9`ccMeO+ZXwmUmM@3m-B~QLqyUi^!hgIzZ%KbI;-*7DjwE{`zR<0 zeso5q{-E!%9a&4 CwVm4h zKt0I-(hm8)#)EiY%?jEu0&&DG$=&JO;m1WZ&`Vm3+QI68Xg0xEQ9wQdlI&`-(1HCi zCoE>MREWWrXF6CK|7!7CExiE(DE-&sIH%>>9rPC&AdiwfU)N^|@(^;oW9%F)L!f@- zuem{oRht!`Q)8to+kyM-xaI%kM2e~XN1`Oto{n4VL@vOJF@&1uiZuY}M^X8mb M%l*-J@fEe`)*cd3+4dqP$7LZK;@&KEU3g{C7|eE5?qRdOxyx4i2#Ofy5@JZYMG z*wk%kQ)(s5%>5dWh7L+IC61zwjn(_ye~!hrofEY|wJUNa9CY}=auicw%26Oh$kE=I z16r|jiLMLq;nL$6Y|LNp2rmqE|L2doOdnhMRv4Rje}#M~7rU$cl;NNYdxNtX+eR2v z?8TBvec<%1m>Vq7@dW%S=z(T4wgFGKHo)I!hU#Iq*#B$?3o&2i@Xq^JeF8gsU3e-D z1ub(kbpBfg`MQ_+yQO~bm!m 7PFHM@GW~{Zx4+%M{(}>a_0OP^g?scLz zs1S9@WYF>XM{SAX2FRe$%%L1k9+lwbyi<%bJ|9UzdY)$NT*StT9w|bgmmS^uxD(Fg z-t|vKNFJ4-t+D$ty6aTTv?wh;I)y_7j-6yJ&c@m3#o0K!R_c)w&g#s^VH6FB)Jw^^ z*_QyJgGjKlm+__eVnXT7D7UwhCGeQV-80|aMx}9^Y|P^5qiD$KZI1T)5^b~NEE0|; zhGG8O`6ho-*?m78-lKSh8o6~~z~lUQ{cmr4!J2=3H1qPMPYJdq0OfeM+I061l=rza zgJae%eN6uZrqg3K!tWWM@u!R_7&5sUAnRvpHU) kgs5mf1gpgVQ0`|7n(LpuN!!(*UOjfdNEBqLJEo}_E>5z*JZ#H$ z9R~#@u%5!ajop>t6HU$Z1NP){#w=%9pu)Uvl{%Elm`Eu3&z862h&4tHd6*dIjPp^g zOx%gac3 lGn}2sQH*LR4c5fTIEaBo#xwg-_iq)>lUQpM258DTOPQ5F? zwfK0Z)OKR=;ExiMtA_ZR;?{>X@IlCC{-RG2d5-&|-P-%$%uc)gueoM^+Z7wfd)-Z+ z9lZYY`MOD>691XWNsS~AUb_gpN5?iUR%IOESL?M(*+1uwRsY@CzBfC3mp3w-fnEnK z>6u3zx~b(_GvQ6zj-2
vKPpBsv3Ne)G>*oC_E zgD?u^jZH`t9LI$oF(--Qglxl%w#}$$g2iiEf>{SClBA)8@r zjU>WptfMt16*n2ff{wWFnWk|aN3oA1!C(Y&RCDN4?6o6lmSY))rYR~4Se!%|MMvOx zfeu4++>T9?Ax9E~)4(l>V}p}XB$xT+r6>aBOaR0Z4kqlH+y-o_*{1i$U50jj^e6EI z_i4~383IeF!O5WOYH6* e|L(f0g7F%p{WB>}^j~0OL%n=5nq6JBYK$*Y6m*D^b3h0MazKL0}5@Q4} z+`imDNN4fhU5LEc`4C0{5IVJ7-?5l9OUHlpV!6}@D6}pCeXeQkJ8iZSY}knwa5mtw z-i|ll-u{kA+|<^&@XAZo0 *{7Gf_{?Yy*@J{*51Wryr$0L(oDu2=$BQMCifTzlr zbsH46cDz;oq%g3V>w(A0mvtLIena(I`IF8tZ%2pVxf0Vb2UlYnX16??XW5D4Fo;G- zXl+dDNO9ZY#Px{nPLoNQqK|h6SZ5r;o-nOC=4{5~Xgwt RV yJGho1fGuc{=b+|2o|cx*frOQ>h~J}-bLS!2~c28D^H zVWyE4qdM0ui;VO?`>Q =>l>&6-wS7du^!9Cc50cz9Yb*I2VsXC^1- zG3XPMp&twG(@VST0?VYuP_+I(`L#y0P)B*uj$B{Xwi>&?;dTr68D+x qK~#!(`O zB>L@sLu=7%ui@3w-d%s>k0IoGj$CK9^10kVDmjpyAz|RBp-^9oN6mp~Uw0%qm Db k$W%fH6K*H|PGdXknvUhYG=`2NoEFfQ_ zI1B%Ha)Ay27qf^S;`R@^$p|bK3>2b)6n@NxEJVpHF+I;$aag z*kM9H8L_|Dmxvz{-yuE%8sLA#=@9-Y%8aOez-ny|fr#_dHsArN?{TKiWEYpn zfFg?bcTJ9LUPgR9?W|8>x}Zc5oXzt5u%Lg8Q&N_NX&WQ;47xmq&^5&vjA+Dyjw;YV zwQQVMa$u{EPLe1LTwM_PUQfG-iohv0gsHab6XcqvB!Cba_I+%2HNytIB8S%z>sy6w zR+5d 0wU1caNxUsdDU>eqGj~L`<%YlnEq&aV z*fTxl3fom#QPo}7nAIW*dtHjH&^o6>$_J#zQJ)! J^$UxNU+FTB;6r(6xC;B`>umeM+ZiAKd$-_Da4c#IxVJ*VNWTgQI!`!-TWKil zMAqT-)}Am%?y@7QPJU|fIh@cWO^<~<{uGkACTt?{4y|qH_YD3l7Y4ZM(6Neomka zx(4~%?1Uy&f$_SQ4#{$$36bv|Cot4oW6-b=vUJV#G3XBtUd*+^e&1S~IPRGflMaa$ z;KfIGlItf&1T4jDC$+~uqjAT)B1oK7o{|Y5fNXaiP@;~-O)+gGH9t@XJEc6vVh%1r z7wKvQw5K(35^D1%%XT_tNL`EJ=_C(>9Y=9dK3ozMg9&&9uQ$KB@xfdKt%UEh7K@ zOjR2`e55t-1?MAud@x*)k6ennEVepgU_G$gl!(hCZzX9;2PG=o=dpXH0)o%enCN{u zQH2?B;EK0-+46-L{!>d4ze+_lPey_d m+)wV?Vao))<4WjL>vsT)QBjqy> z<2YMh^$ktRMdNQEceanKW!oCsqN-qQlZr)|AS;%lsJ76PZ?-70OyYW?sRMs5rEX|) zHFz>GYI~QO-p27qhi`A0EDxps__rk!&2|#&eMUL`g2IcOMVyjwhP~?1CSu1|kZ;>{ z8XI9ME?aq(s=8stLv<&FQiafy3|R<`QqFgjm31wV!z0$9bo`{SQU{NNGnp6rHb^`v z+02Yi*)x4o*10~gyvX#;miF}7=+Ub(#t42lL^%qQySAm*86;v?@0Wg)Z&OB`m>#yP zmekWqsj972gLa-ptLkj51C-nbuq8Ecra|AeL3&VO8%{?mcEmVc@Tk@UJ3zgIL8%7@ zT)P4OHq)g%Q#rlLKqD<9zBcOiV(Tn>lR?meGZqV(evUyCr8SabvELF11^03>uDzC3 zDaa8M#&B?^TyS#Ge4vLd?|au_rysEd{XhjAf+vuK;2pXA^lS-Ugl7VZh}!KaCeAAz z2gZrk27ojAf@!s3?c7dZ$}OCxHzvfOK+C96T4!6OW^i57j;NAi>n&Aww;s+%G)