From b9d8eec4adba057e5a01349be9087f5693906935 Mon Sep 17 00:00:00 2001 From: Sebastian Korfmann Date: Wed, 6 Sep 2023 11:18:41 +0200 Subject: [PATCH] chore(repo): add VS Code workspace file (#3929) Make it easier to navigate around the various sub projects in the mono repo by using a workspace configuration file https://code.visualstudio.com/docs/editor/multi-root-workspaces Not exactly sure if that structure makes sense, but it's a starting point. ![Screenshot 2023-08-23 at 13 51 04](https://github.com/winglang/wing/assets/136789/defbf0cd-f98e-489a-a363-f507d5fa9bce) Thoughts? ## Checklist - [ ] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [ ] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- docs/docs/package.json | 7 ++ package.json | 3 +- pnpm-lock.yaml | 50 +++++++- pnpm-workspace.yaml | 1 + tools/generate-workspace/README.md | 18 +++ .../bin/generate-workspace.cjs | 10 ++ tools/generate-workspace/package.json | 30 +++++ tools/generate-workspace/screenshot.png | Bin 0 -> 57159 bytes tools/generate-workspace/src/cli.ts | 118 ++++++++++++++++++ tools/generate-workspace/tsconfig.json | 9 ++ wing.code-workspace | 65 ++++++++++ 11 files changed, 307 insertions(+), 4 deletions(-) create mode 100644 docs/docs/package.json create mode 100644 tools/generate-workspace/README.md create mode 100755 tools/generate-workspace/bin/generate-workspace.cjs create mode 100644 tools/generate-workspace/package.json create mode 100644 tools/generate-workspace/screenshot.png create mode 100644 tools/generate-workspace/src/cli.ts create mode 100644 tools/generate-workspace/tsconfig.json create mode 100644 wing.code-workspace diff --git a/docs/docs/package.json b/docs/docs/package.json new file mode 100644 index 00000000000..8a7f2b80af1 --- /dev/null +++ b/docs/docs/package.json @@ -0,0 +1,7 @@ +{ + "name": "docs", + "private": true, + "volta": { + "extends": "../../../package.json" + } +} diff --git a/package.json b/package.json index 919a2a11d6f..56ff173def6 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "private": true, "devDependencies": { "bump-pack": "workspace:^", + "generate-workspace": "workspace:^", "turbo": "^1.10.13" }, "scripts": { @@ -14,7 +15,7 @@ "test:ci": "turbo default --color --concurrency 1 && turbo compile post-compile lint eslint test test:playwright --color --filter=!hangar", "docs": "./scripts/docsite.sh", "install": "bash scripts/setup_wasi.sh", - "postinstall": "link-bundles", + "postinstall": "link-bundles && generate-workspace", "wing": "turbo compile --filter=winglang --output-logs=errors-only && ./apps/wing/bin/wing" }, "volta": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8fa1a23539..752e59f5b1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,9 @@ importers: bump-pack: specifier: workspace:^ version: link:tools/bump-pack + generate-workspace: + specifier: workspace:^ + version: link:tools/generate-workspace turbo: specifier: ^1.10.13 version: 1.10.13 @@ -965,6 +968,8 @@ importers: specifier: ^5.2.2 version: 5.2.2 + docs/docs: {} + examples/tests/error: {} examples/tests/invalid: @@ -1327,6 +1332,34 @@ importers: specifier: ^5.2.2 version: 5.2.2 + tools/generate-workspace: + dependencies: + '@pnpm/find-workspace-dir': + specifier: ^6.0.2 + version: 6.0.2 + '@pnpm/workspace.find-packages': + specifier: ^1.0.1 + version: 1.0.5(@pnpm/logger@5.0.0) + npm-which: + specifier: ^3.0.1 + version: 3.0.1 + tsx: + specifier: ^3.12.7 + version: 3.12.7 + devDependencies: + '@types/fs-extra': + specifier: ^11 + version: 11.0.1 + '@types/node': + specifier: ^18.16.18 + version: 18.17.13 + '@types/semver': + specifier: ^7.5.0 + version: 7.5.1 + typescript: + specifier: ^5.1.3 + version: 5.1.6 + tools/hangar: devDependencies: '@wingconsole/app': @@ -12402,7 +12435,7 @@ packages: dependencies: semver: 7.5.4 shelljs: 0.8.5 - typescript: 5.3.0-dev.20230905 + typescript: 5.3.0-dev.20230906 dev: true /dset@3.1.2: @@ -21209,6 +21242,17 @@ packages: typescript: 5.2.2 dev: false + /tsx@3.12.7: + resolution: {integrity: sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==} + hasBin: true + dependencies: + '@esbuild-kit/cjs-loader': 2.4.2 + '@esbuild-kit/core-utils': 3.2.2 + '@esbuild-kit/esm-loader': 2.5.5 + optionalDependencies: + fsevents: 2.3.3 + dev: false + /tsx@3.12.8: resolution: {integrity: sha512-Lt9KYaRGF023tlLInPj8rgHwsZU8qWLBj4iRXNWxTfjIkU7canGL806AqKear1j722plHuiYNcL2ZCo6uS9UJA==} hasBin: true @@ -21443,8 +21487,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - /typescript@5.3.0-dev.20230905: - resolution: {integrity: sha512-Nl9MoKWN0YYlCvQnw850L4ZgqdmqwVGCi9cAoQDw4PsqRGaWAi9HKizS9xu0q4qgKKsEKetWCZHT8dBtJTGaMg==} + /typescript@5.3.0-dev.20230906: + resolution: {integrity: sha512-7dCmQgfQ4i38daoPCCert+rM6gLxBpxRdjncJkHkJV4CWvNZsRX+RVTusojkqGAtW9vqB0+/8iDH6CZ0PDxghg==} engines: {node: '>=14.17'} hasBin: true dev: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index bf601137be2..ee1a2596cb9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,7 @@ packages: - "apps/*" - "libs/*" - "tools/*" + - "docs/docs" - "apps/wing-console/packages/*" - "apps/wing-console/console/*" - "apps/wing-console/tools/*" diff --git a/tools/generate-workspace/README.md b/tools/generate-workspace/README.md new file mode 100644 index 00000000000..e3fbcfdd9d2 --- /dev/null +++ b/tools/generate-workspace/README.md @@ -0,0 +1,18 @@ +# Generate-Workspace CLI + +The `generate-workspace` CLI is a tool that generates a Visual Studio Code [multi-root](https://code.visualstudio.com/docs/editor/multi-root-workspaces) workspace file based on the configuration of a pnpm [workspace](https://pnpm.io/workspaces). + +![screenshot](./screenshot.png) + +## How it works + +The CLI scans the pnpm workspace configuration and creates a `wing.code-workspace` file that Visual Studio Code can use to open multiple projects in the same window. This is particularly useful in a monorepo setup where you might have multiple packages that you want to work with at the same time. + +The generated workspace file includes all the packages in the pnpm workspace, except for those specified in the `ignoreList` in `cli.ts`. The names of the packages in the workspace file are either their actual package names or the names specified in the `nameMapping` in `cli.ts`, if present. + +## Usage + +To use the `generate-workspace` CLI, run the following command in your terminal in the this directory: `npx generate-workspace` + + + diff --git a/tools/generate-workspace/bin/generate-workspace.cjs b/tools/generate-workspace/bin/generate-workspace.cjs new file mode 100755 index 00000000000..5be1bffa694 --- /dev/null +++ b/tools/generate-workspace/bin/generate-workspace.cjs @@ -0,0 +1,10 @@ +#!/usr/bin/env -S node +const { execSync } = require("node:child_process"); +const { resolve, relative } = require("node:path"); + +const which = require("npm-which")(__dirname); +const tsx = relative(process.cwd(), which.sync("tsx")); +const cliSource = relative(process.cwd(), resolve(__dirname, "../src/cli.ts")); +execSync(`${tsx} ${cliSource} ${process.argv.slice(2).join(" ")}`, { + stdio: "inherit", +}); diff --git a/tools/generate-workspace/package.json b/tools/generate-workspace/package.json new file mode 100644 index 00000000000..78725c35fc9 --- /dev/null +++ b/tools/generate-workspace/package.json @@ -0,0 +1,30 @@ +{ + "name": "generate-workspace", + "version": "0.0.0", + "private": true, + "bin": { + "generate-workspace": "./bin/generate-workspace.cjs" + }, + "exports": null, + "sideEffects": false, + "files": [ + "dist" + ], + "type": "module", + "scripts": {}, + "devDependencies": { + "@types/fs-extra": "^11", + "@types/node": "^18.16.18", + "@types/semver": "^7.5.0", + "typescript": "^5.1.3" + }, + "dependencies": { + "@pnpm/find-workspace-dir": "^6.0.2", + "@pnpm/workspace.find-packages": "^1.0.1", + "tsx": "^3.12.7", + "npm-which": "^3.0.1" + }, + "volta": { + "extends": "../../package.json" + } +} diff --git a/tools/generate-workspace/screenshot.png b/tools/generate-workspace/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c2f81842b336da207889158dbf6638d654b2c7ff GIT binary patch literal 57159 zcmd?Rby!th_bv>Z?(XiC?v_SU%1sEHZs~4OM7lvhK)So6yOj<>TDrU8EFSfF-{1NE z`TjiTI$jIeuD#}5bImp9821?WJ^ZMqB8P@dj0^<@g{B}ctquhRA_RW&5#fO|-Gn?9 zP*BiDR#H-G3Q|&(YEJg%R<>qPP>eBl(IYHDj--8tCb~7$&jbbbG6ljnp1VzitD&Q? z#CKI&R2SZRc-7^S#RvUrbV^Ktc?_VS8yHhyLQq#BC7og`>D%PA?Yf-Lzbtmo7|B<) zw{$3KOs{|$(40>GOzOw2532sRy9SE1DPz)0xwy*wRghC;gqf{* z8EA-xDD_s3ywrD$dq^`^mBcFaPIEJ8)92qUnRyuIsHS=ZaEANcaU_l2K?i?|4S&cW zx=BNdmSu?QVCGykHJf9PRC!x)#KXjMbBxI1kqcj1;%@;yAHQ8@d2aG$=RIA}+Ow_Z zVy}g!(MBY>q(@>PDN4Jfg`PHtYh(YHZ0HdSg68GC%w=2(B?6G|dzo zUQECObFOU$RxnpqhGGUjBSJxcu!4Fz3l01b13yquFtNc<2*7V_;72+W^!Hm3VJ6JK zpYxwCe6As-paA^VFmW<7d*f_r?^67_Dh23j+Da4b0#;TMGO@Q~GcvU|He>U!b9ib3 zCE_6je6%xjF{1Ravwh<%&7gCp&{nH%ymngNRi;II0JG;BPJDWQLN-_{dA*$|NI`OnTOSX?)1j_ z&tm}($o}*VJ0}|l`@ekyO+}v03aMFnnAz$`TiF5A1KdN5k6%#apX>iW-~8u}|J4%w zpO(DbeE;3@zrOk3TWUF*IZ4^u0k?D!`_G&C)A+x?{L@f`{prd7YbJhA^FL>Sc@{$! zVgL7?i6LuB5D!5?NkAz`KiBkt-usN;gWGf4yCkvILIAftE?FIjCS4@2^*l6091H7t zDDHDFNqg#^w;=zXx5y!H5#4ca?0N@(og2ciHpa(DoZ*?U?E(C-76@c-7Yzer1f0;$!Cr`Mbw@2Bjv z>izC@b=n@}^gKVOFq!m*tJm(ds5cyu?Q9MvusCgvJ{R;j3fTKmJyf`$eb1~_R3mcK z9u&)i$XB1rh- zY=2aF?|oZr@ix8KBRZM4Z}U)6{oapGCPW-$t%rp4^}ghLhByNjmXzu4^io{4jlvvX zch78P9NnujeaE`n+rw0|qvZ!&BF9)`c`dvD9LF&PdDP?7*zW&m)NzZLva`)6@yWUawG!Zs<+%o zsaKoZxuPk4>yPQ8<2uPxWm8DFnl*9#6~PZbP-!B!o@$TZU-o)F*KOZRz3l0<9w&W=h|9k=DELm)@5s9~eafQ=!!-_=Xc^@JJI)o#uzmu+{0Q_etG`St{; ze0hD(Bj!a|$#_cv*B!$QUi}s?ncOG}@xiO?g>Qs=@Ws233e$J*wGvmlZl+0hMZ8_Ot=!T zGaRTK=4E%VzoB5u>w^$54wA%ty$ZzlFo~kXbXgoplpy<`xXfbx?%|mok9!C*25%2l zqv+U5l-rR<%MDe3wE1UD792;r?9X+jq}guDgyCyUqda4Cky{Q5beMVF>MFA#du)?B3R@+?wD^T4_ul$J>1Q*o_m8xOt#>CsEGS4? z@hE1kQT)&_iA?%hbMq)SzTZou9n>K+sOOz-jtr8y<8r16pAK$M* zmVdgqT=FMUX=zE2=b?#P$#LCv+wohqZj=d2Jh|CjnB)#;VV_V4fCWhffM_^KHI$## z+RP+0x{`D^E|Cg4^?$_aGwx}U^Ev%CQ)M*)pR~0zMS<(yu@X!5iM>d(kRF(dsCxU( zNV56KdG5TxSUrf({kh23!`7Wa>$9!wD5kK%&+hmy-&O9cAFW8S)ll6mCd<1G+9L%M0XmbtK+Pc@d>JPUik|+iAZB1vL-xzz^l& z%z5)WnR=EqQ!OpFhSUIFnL!Kl{p}?mE50fcsTdU-hw^(oIugF_#iX3qP3YE42g#gR zpj`yeJK6d-EvUsR8ecCL5xV21XqXN#irp|PsLf9|41M`N;&BPJjfDR*9ztj#Pk28;Lhu{sA5MectmVir3?;Q3~0nWdgT;`7i&lLft2Qyf$uOg;b^GN)Qx`V)xRO~ z7Lx95bfytngmx7Y+!_N7AS))Z zB|5DSD(+5?40s01nGWKmV9&E*Pd1R?e|>V8Kt%q4A0?u$SZBXvE$~q+6FxJ7WM-hz z)h4#s2I&ofhB)x{WBVw|H>=rx1<@47f!sRD_-vyg{OSS<2$H6nMVc~pvYKPAUfUfrK0c`nRrAd(*~^?t#n?a?wc$L^jGJ5l#{7f&TGSm-KdyE4i0E&XbD=yejFF4mPUIB zTwRgPx!=G`G*dN0mwwBjmEn{TY$+fvHasD@_;{YsX1+mEWZCpLLQQQ8o> zs`&v+>Os@xfn9-lbukaui~C$TkceoBu!CMBiQTa7SBP&YTFDv30TFlJPy$QqXl+Maf3pe#ZO_1Dex+esdzMN7c_A3BG*yk=vHIwI&#;Y}T(uf*9d)w5b1c0b)f zTMH}XY(*1eaZ$^{C%V7I(4GK4C?&4j ziIj^X=XB#PwP!`Ulejoo$gbn>GgqB8%z|`uT4(mcYddVA2CMo+kqR2vNxttm&(Gj1 zoPxQDSys#f{37>72Y7cD56%PL`|@D=^@T@?R&kv!HR;TYXuy*VTpim3`;Bahq@{0= zlo%<7)61oyaiovj`)9tYEZ{-W961e;UIy3BkA$B4I^TKbCY47 zZ?2KuEfUOowDRF_kigK#oS|v$2BC$Y(gbf-7{N^Wu!&{jWduY8^q6f#sjvvRhGX_b)Xc;{Ax!}rGE{pF3y{*VFQ|=1G zu<5YR0`=;%A_~*T1{tyqT7qAgnhqtt-tPl_0N=G5GchOTa79ZPV`a9>vsM+B7+jG+ zOws`?>(zXEdst4@;&rYuMAG)?SE-m@P+)07WHJ2a6C2WiN8l9B%1ZWBu)0+6S(5nU z&$#dwB>f5H)H=0QV(RLkDzizl?1 z+X47JKV77|2?st4N9i)1oQ|Y|bp4&Qr?X@fr|#Y%Wh;-pLu;?#!DHdHo+)EF-Sm%1 zdu=)oO$&uGuV){jLA~~oftW>{`br;?uL6%PZwvZq$x?|_{g6o=@GS=(BT{Xt;A*d0 zFxbAc{`r)@;pd(+`BtCnNoGR#u;CP57OgQ59P&-kTdU{tP}DHDNj#Qnib8Hak*m~* z8AcUupFlL=4AR@rjIdq+4rx{U>a^};Lf4P*aa`6(3t2<3MD9H@o_dB+{YAF*l=l>! zm_tuA7m~ojv4EMn>VmsWU`%6%_~D{tCV&ZgAMnwBMTyt-ze6%1ZNu&!cb(5C;Va?R zZq0c)pG3fJAPJc&c)4a2Xb;~RB@TbsH)JaXk;SGAq@|Le2&e5x<0Af1Ym@JUNXq}F zYKcFdMh?C9<;0SI-{ST7;UM-Gs8-C-C{Hqxh9$7_ah?f(!i%lak+kb{%~G$ZIV;?z z2;(N_t29cVn{Bz?&0miymN*L9ud9h z666!t5ha?yU-X#9cYWLs^PJHVKVgqH=JQn_1;p+53+V*{R!_%gaR)v^w-T^7AH`M% zPB-JWu}c8qK)CllBlri*iu=_O)j3t&RPif;!@sY9tYjY56~A3ey4KQuK&N z3H3L#Ao2u&xy>T}%xUxvFr_&+hR~ot$%nvpoXmE_|Jg-SVcwrB{tI6r|T25d9&5jeQ{OXM$A-_e4IlEdr2O?uhE}Lm@Sqf3}Fgzk6A|~&Py-+-gCB%@-)gHxe zX21Iz*X!N#mde%7_%Tcx^h__a;tdx-;tn-9j2wGv#^g_PB5wo>gmBI}%^qJyno{`f zWA1Jb+p665nLQt_3Cy}fDqolaA@G#NR|(okaxyl(`iFzcBA4y)f#nXYr-X)C=et7k zQ;)DTKD#O)*730)@asup*3#{bNZqRpFLwg~!n5L69`m#UmOr(&3RE;P2|NSKAV^SQMHa5XjCkp_K6Y`Nbj0(8_v~y8E{15XudMG*dAS>yMDOsIa&19h_FiEH78SW<$|Yd6h|+uTWihoy3r-6 zekmQ(LJ&Dz0E-jmpZrxj0!4GNv~0GlGM$J|I4bEZyUslYB^N&H)%ZowK;p9|Y{EK} z*?y0^E6z`%w=fCZHq#~WaVszMub91dCfm5&_7JUR%7S>TC#50J3Au9GGRtyM;ZX4L z!CB@b=|)XIYOE%h178BpyKWHJ=$-K%pMdNPn{q0j78>+a#!yih$iWyU%yJKL-$)T|eG0NL~4D*+JiZcb{-TppD7 z=PD*OC!+Mi${~gWOG+VzS_Zf6Jqp3#$@-9T;#84V+~fVB|Bly>Dzo5$?K-<+V0DbQ zc)KUSJHI|$Y?%VmI^QB5p`waUU3aGkHZ%OmS^TC;be_^ng&w=&Qo*P(KG(*6Mz@!T z?0`q8p;tWk`Blpw*ck>=h34v3o8Ldj0ddC=kVK;Pf4I(9d}v^U#~`;&-Wx2kt+p7^ z?vpqj^<~tl%GvP-R#&(ht`BOd6OwsQD0LtzRIsX>igK%q zX>PPzeLT;DERfKzU`m4c-Gs>Gz!gV(a^ZwVizL#gK$;1b9s(e(Hy|)wrN{Ap64aU8 zBN>zWuQKV~#bnMnSo_;_(1XG9W*EB|_rp@J(o2s)iwGddXaRCM*fyFH-%;?GSye@+ z#yy_T+h66QY9-?NGpBQ|k#&s!1oA@hp?E9<7yEkmOmA4&eI%EKVIFbFjxGs1?tkpK zAZBu!P@CT0)CvtAW~&B5tInX2Ob@JdeYh(lZ1;cgj3X5~Q%y7DfAiB4y=E@<3(7V$ z;mq~v=Bu{Zn<#;YhTUZ`jvWtsx#S@r9HT35xk#yJWjn?sA^dryT?&)91Hl|kM7_%o zs)d8epF++)ZK43)jIFHBDMAVYt0>{!83h~M--OB$(-Yb8VrJtol|-wZ`+BZFM&{#$8U)roIT~)fwXj}Dxm98`?M_!*whFIx4W@#MQQNV}(tUgVFjg4>5QzjX1 zv!4z=_TK|~tCWSiBh^5ARc>&sdst_ucYo4R@vwiPYbAo6!tXzKl^WOU@jT6@q@=+r z9EpE2v)Q|TcPOR2Xhj+&@OZC!A5}cEwY9331+Cb>BIhzc!}!tnRGTVs8J&nIw|BCez3nb*6|yl6ZEo!^^%0vc+}qa9W6TfVV(g35htOJf4u6}M zP+?sFWKdcU6>?3f4?Vs}<+nHB*3o0f#IhvEM8^ans^umVkG@6K4mdh;;AJ$akTyUq zNSD05*iYy|82Mt*;x%5X$De>UQ$gMntegkX8k~my_qEvK$%7t1J1zX5{5LnpeH5uO5Uh^FWN%BrnzIHv zZhm$re%#LBttJ%273IQ8QH+cr2Ew=cO~~RocS2Y za;ifbq<*=^;t=w`$?4-euJ4>rE$;&zhop)5R+SQHHfeRejUil#k+Uwmm)0)3d#)Ar zxY_jqWbz9v1K~d<5#!jxAysTsY6VxuMS&<6?H^c zSvbZUCM~~ST`t81dtSTp&hWYI=>;R@htN&kG9^|(T6l(;lf$ZTI5urv-;CKOUD524 zpGmyyFi7p=gm`+Ly0GtV6MuKbBzA;TLfV2d#4HYIPZPgGK2i+icUHmx_k^%ni1Jxa z_BVIWSGXP_(PAVo*S?2CQ%MsT!zF0wJ?jxZY!1@E8+8Xm`@kI;G`bXqNwkwR*F!ym zlw7x={4qrBves&rP|8-eEYUC}l2baPTtkOb(8GGBN9F0A3`u700G`0M;9)ik+iPj3bLvji5{3!|> z`XK=aeu>v+x`98J6qnOu2g)B+xPv)MC0%5@60t-Hh~T*GQ`{D)f=ro!#tHG(rvu zB>oWoeT}S%vzNEq;3#dseuS5>C^#TL_7(1K36KhHz=9|NTbh0I?EO~vf#)6$>D<`n zl3!S5fcNk(iyVWpkFVu$h-<1vq!nKveQ{jq2OcNfb3MIR|3aFMt64dzeKX6X@B1Js zOdsa`2d=Uk*PFRon}j&pvSa#>P)pFT!#xyYK48IXBXkP;S%-qjj(as1Gc^3?Z zNaju_g_nS@7gtL*x&Z1Z#xFrfM&HW(^tG<-nDV=gFUX?|@&+$r=8syH$qD*v@j`($i>08@BK2;#(BwGuFA z#|VHr%I{?O>=#*+;VV^&J&F(<0Wyf!*UO>Bbyu5IGr(iqxe_z50HY1Xi}=?7LxxMG z%7W{R9YdY(?ZvjWeq_jHVjeeOcwc9v$kjw`^VmqFJuE<3zykrrCiW=1`GNM#)!9|& z`(($S`}d4uu7bJYswlw+v=^Em`rAnp85H5u^o3l#w1A~*B+&T&_8HqK`r=(pA#p1b z;n_-lKtR3r{YC`8Fqn@csw~L$Q+8z7ZU~wzWN{igi1`jt1g`kn;8Akh2YBy1iG-qL zyM5MQMmLJ%gL92o*EM)MuvmeGkYjbNQK>ok9-yn z(ihfv-=*aT(3Lw#zfX3-z=TaM^0-`ZZ&9)6*aT^af;r!HkhU=hf%B_NGzfK*{ciW` zg^G)ogk*B^SE4)O&O2ENGjVpED;^f%3cR$XK+rVNyf%DYRV4FCOb|5KOzOLR3GrGC zU8o|LLdi$}DFAj!i?h3s0T}nFI>-M9Ck-@xt6zz~_gW6Nwg*jWlQYX# zin2gHKgW6VjrAI4NmS&aCS0CGCa7`*){khJMuHAY*aNT3q^qUv)kwk zMYZqPaR}{LeA7-&e581U*DhBbC=Od9Rzci=0A^a259N2ivTZj8JrcgghY?SIIaBs} zA*@K`fF(K_>3jXv!Wh*s*M7iFUlc`o+$5G=hq$cjnuN&qdfwdFWNyGW6hsQ8mpVZV zVX>~a>p;i`u0BnJC6$8G7`##$*!b2)tg==voM(7IX0_1RVnk=lAnM&(bVvJh0>{f2 zV5J8A(Z7E}LIY=o22}EKb`7z+b3XL)p8x2cP+hwCboz-iQhFW)bG|o!nMB3qML0nh z7f)xhJ${HvHM$5sub8}&5}hNo6fM_@%*HV1Qu^Ul(HAQXi#qAm1M@(+R*G)!UnOn0zW51NKZmV7>9(OQk?Xu$zY>~7QB zNA-JbLdI(UN3pet+7DD5^h}PGwm-1DI_zxU_Q34~6SUwH&MDa~yv7!`UyW*0ks@j_ z#oIhaB7~~^hy%}~x(aeNE(ZxLZxzDq6$iML(mM;#?sTBI8b_buaWw37C{rw)BD_Ud zT&#tIzC?IF1#tG&Ot#u4zF{9SPtVLFKpyynwE4=ZdD`D7(Up#rS|1<0^?Q*ie9vOA zKOWh4q~jub_<@N4c2?CD?F+B_fxc_xW5rR^D7q>H!yoq=+mRZrXz@@Y8 zq&XTUwa~J7gP$KJ=N1m^5U{t3Sc&^TY`$yN`Rucj4c$@b?|!#1pjBTUrEOu{!dNl=mK_GfGU|M9^eHeM1HFu>XM(88u%^omDV&Y(!g6Egs=m;ap6&{L zU!v)54=3WD3|3kkR7v3(Z~^s1#yrKciYA z5w!;RVOH2+95wzDi3<2_GLA8XT|d(Fn|A_WnPpO>Ap{T~!6`k*nXGyREhGbBe-lIz z39z9B2~>prE8ft>h&S&n0-vo>Sys3Q9|+HlPqU`o;!x(4_z8oL10TRJ2W0rLA#f$| zAchd#-4;ptPD6xFm}wH*@3}p28z!abxzmj+hO1U{sAA8wzgWN4dAmPL1Soydl$Qbi zLwkaKs%XKcM6$S?_2%KMLH{dqZ@dF{?aXAA+0wNJkHU#$c!{CEckL*Eb$>a-@Yv+r z3VQ0IY@Gs{h$6ZdNT2b?&R4d!zfojKA~cijK%+P&PfRPKx~5-|8_iwtdKhJPpr;D8 zPY_JwqY7v{20n)mlGQhwud_49w+GRvi7ek)?hEIcj=En}fqUS5Uhf@{Be4Xdd(6)i zbGW4C(@3Yda=bUmb2IIRl)=P{>;#!1QA?|SFbb%vW=bjR^D5D+FVn$j=)CL|1?Ov= zIcb444SdhFlFa%%3>@}+`yKeES3$lL_{5i9juFZYl+p|SHCm{i6@^Kyug=D9gx|V6 z`9BNnfJdq{ZbR?Vq#Mk%1q1CO%^nX&vcfuDkF^K`U&%Lq!obz3rvvR@>vlJWtXZj0q513hXZLlfr!PCgibr;+~d~K&(`xb6rib5h%Yd5bgvr?*+`m5B_fgF*%0KvB}08JcL zl#!YoIxcMw9$I_3HT%EOQ0Bpqel~|PU%DRJFv76 z81Mq2N3XH$hcrv~8tl#O<(~Kck|6Bqm%~6wGC?P~rtRxu_)HPKBKE7S6ct!Z z#H#p;qaATIf7vjnATN~mvT~SU6;7K4jGs0xu7qNAj+9Pvr`P_S85`Sa=}IlVZp-I- zJ&CQA9H}tLOriY+l>N80US+Yk%c1Cr2}zf%j^l7xnztDE8IU(szu#)%`FRR^a#Pv2!#ITO zGj@mMum$9iTk~em@>x%W-h_59ksxl|%_^ZdUxVR4lD(*%FyUCjxg{3|&A!n`xT;sv zw}j<@fy0&z7&5XJxlzBeJHlD6Px^k{m9=Ppt6IZZhOIvUP&w2ucjSB z*e#VVrHM7lUd2moE%}?c8tz%$bV~*oQYu|0GT~G!)_r#4a0S#{r>g)qg@+3!8~>P$ zFvP#o7Vuc$Me#w}Hd0GC9?D0zf*(2%Bdq+y5&U15FmhlcM)y4N3jZ9&0EZFs?H%VIl0yQ7 zL@N;(^S^ZhCu>U|PW4xEDNhNI6R;pt$3H{~W#B92mcPO66m$typ!DQ&cbC1?mC$0JYaQ;uxJ2Qxs}1zk9zK}R&c5X<`M zjpvKl)1+~E&6+;isF?SsvI^J6{5gL8D-znaW*ELB`|dyKNovvw>)}@-ZAxP(2MPu$vy!n@4dE zUvzS*@!Wa5NK0=Zfu(*pm48Mm@|_%SiJ#0IfAg=(EWO|Z0avloyGG$4p9aQMX>Xz- z#YIOAubO5^$XofS^F2P;&UYhD{Z`p*_Ea``mfPoho`vc+!F{X@BY6o{r`1DzQWaa# z{BrTl^PBOlHLiEd^R_1oy~A}UTsVK;3v7zS93ZhpM{~)2n6CG|)n)=TqdsY(KS9j)sVtruX{puDqTUrzvtl;F{b*`|uc839dX;(L_M zB^A_mooYEY7L?v^{g_s~0&R*B*UmBnVG-clhVk3@VYeAnn^0liy@HR(3oIg?z}=UhSCo45j5%U>D?z< zKgHAeHTsdz6*SbFtyMMJB`gpv`+(%64W&IFFdXwKLFkf;7ArK%z0F+RE%^% zK{Xft1=e8Bk}tR1o3Fcjnx}M>90Ps&P#-_Kw|!?LsqaHQ!9=m!X;A6o;bO(q)rT;f z{md5xt`VYq!I2xdjYVd_pQrw381n4|&><+{>{>(mmyB#`b@GAo>z4>&9_ny?h^Rj~ zq-CYMF?HJfO0kI|h-2nc3x1c^LT5y00^4`tyA8M6sh51@sUql1 z1#h+QZCpYmWPkryLh`EYeg7zi^Y#|FFQLsW)>V(Y=&A`>7P%YwH%kVEROY z?hj|ZT+@Ar5tTxaL1~1mS6daQ65$iMtrsrcXCKhPy`fMRBxDu1yk!+LvH1>*^V9JS zgPfoLv2B#DSOL7CM5HF@Fl;9h6YO^i#t4Vx?>;U#k)BJLh67A#efT;SkO@x&vXw~M zskA(hL74CHLZ&`&xOiT!eZQ|yN-|cl zz3gy_9dV$ZGD<>=0WqW%&qz%U#)|yde_Y+-^Z0Fv*ba%Eo@jaY%FAxh2eE=L7Y0$Ayl86 zuX~1dzMa4*aEUjn3TyKtneajJkHN+VJ#3?V9C+ibR?V|^SZD$#+Z#?4p+#qsW8CwC z%UtQ*-W*;-3ulQ2C72zR1zz&d%G0#1GQ5wtW(ou&w(&JG48V1}jv-SEyn2^`DDGJKBq6>`7jD4N@!#%#880 z*1|TV;S(4cC7ABb##DKohX&LJ_;LtE4cSa1P=r~P_wB|0IH^?R+K5XtCsv8P^VU;~ z=dME#_uHt0$y4loWE&*1iFR#2(R#;C@Mh*^9^$y~VZ}$+VIfjM*QS!lr_k>o*D0}_ zR~d+JAbq-C!~Z!_Rere|U%`k>6~vG6=!aCYYW%a|<;NRe>@!qqi9^FPu+ z)yzGw{PJS{ai%#cpyb{Uxv%YGFbUpw^(vm`KKAA{oY3r_$b0j2r=hsVH$*vaO(6FU9~jtl<6eLNK&YJ;r;Dn z4FW3Fpo%GIvQ6ql<&pDM+)pAaAOKfy(Amj66wefgEu+7jx6l^3gAVdm9p)7i3l30L z{8@j~yE)O+mhkG#To0@TGWya3Ck^d(?Bi)G7PSgG@2rGJ&$FpB<-w!R)2xV<2@4a) z$d6mpIPGR)Q_DbiI5GPDdMKeW+l}F`pwjtEh?Dsg&>aK)1UlaWdUyCj?R~NHFWfGJ z+t68AzsO?VmRC@d@@jkCSq=MNpC$+~D(#UO&VqZet;cey_Rc z0CrF$CSj{kKhK|)KpD79vmC+{yWG`F{x8V8q6UO)VdxY8g1l830FD{Vf`h6sE_Wy^{ZeyjDOJc$L-lpBs4qV!aRoK78uGAnyq1wTpo4&wc=) zUUwKE-D$3<#Qcjtf#Kp3wr+7m{Jk%w0f10f-$%UvcW6F9uSYT;tp2_4F)(;6c3W2I zzxZ<*=rx#KNQvg}eM5l3hkF>AQ2m_)XhWb^pD`oizxS1B1_s}aLW1&V+MtmB|4d1s zn&C%^0d+ixP?6Bk zcn_@70Zri0EA78CFA+-pv<9NY)9J(?n_mJ_Pimk%D9$pV+H8oP+v0mXP^Of+3c?Qq ziUS5p_3Aa7FtMJpbn&b@<0j(cImZ+_jV{|F(>?NkW>mfq_KxBiP9QA&HBkRE08q0) zV!Ld-#wtwOQpWUXxg(a_LPhHm;5l;)+x&tvt=IqwLL4A;8ai3$)ZiiFHjfVp36b80 zVWImo1(OoM6u@NC{0}(wI)%rITqlVg z?`eWg=Q~;n(^Y1QQJ#bf|E{Ri0Gc$B(%0SAVOTW5FCHI)a`o!dvB}8j6cbsi%s84Qe5vc;e|L46+tlO8A zdrNIghgGb=Ui^J5Q$WkRni%?%h|4q@P>v~l z7IK~J>&N_HAKrX2$kMw=vf#i35FBxbZI1?@^&X$Mvg%ZM+3m@{- z<6Opzx$bC2b#`kQ^!_m>5-;eM5m97Q`Sv5MJ`Qr34dw*w&28@+J(q7j8&?dT*s?a! zJ4rSx2iFz#z_}fFZ_duw+q3J{**X@=`rA#>jd#5-n~}oK{$m0ur!WyYwY9o^@wl5h{(u9yZO3-bW!ivBG0@KinJ*-)+Z*I0}JeX5_Wt$+JFK_{3%6Y>Mwg#Y`7 zK{<)!p7dWHAl8)ukZ7I&vWLOf?hCndcl-5Au;PHKQK?FdRz~Xn<~;5LP`LFZO(PO; z$o%okBEy#+;Amoi)jb5fv0;z&zm>L>hys$3nm6}pHP%zwfW3PLi0sh1eLYKQd~eRU zO#3klH49_ky?d8@P0VLo@EwCxfD+(t0q0VdY}MhTo-K>!ngRUF?P~;}lP}x_7J5VX zzcvx{{OR2TH8+ZW51!dBJCibiOokrwa=j8AwFqzlxTtly`t8P!2R{YBy6z@2YXGeB zHSkn9rUS9$yNGrDhpo3NZ+FCw*OgVb{a!H7l_&wtDu|QDhHFXM(o%?s$Ff1Q z{2>!4=hDGvOQSd<2UKV(fP2Z`5p~&$R{AWY1+bb%brXP?unhgmUb7gsHUscYcFG-)?RM#oD@0O=AE-a7ir>=$W+4F(W4!<>PoD&1PJ6SQNg_8O zZOo8_Y`G|)VlzI{P0;v;N;O?%aAxJ^e7ER(3a`zJ#b(d-v+W7Cb<{5m7-CnMK;Wf! zuBfM3f=7)}!m%aZ`PqHZ>Z+_;DG;?sKI4-txHHA9lkx|KfN4P+DG|DMFSOV#Q)M$Ktzg6vvB$w?hN5@Om%1m^n zO2G9i0_Jr^eSK>zJJ;iQ^+kbxgTwO!pjd*NEa(`J8-*8s$pC6uU*=UaaY^X6cOETz zAAY(9X5Sj@mRD?Z71I20vkU6@0&`%|6^zE^cjrNt8@a{)4%0`m(QSVxc4He9nX$66 z0(uS~6EF&}cY@v*CC#Vbg^SQ^z5;ki(bBTuDPKN#15+7T;s5BjJzbj0%QEuYVyI(5 z%ORmUM1_aP|8cGn&_(&ua&iN)betP^??ea$T&eXNT@=vj7I!+AABMRr?t zD*~=;in7J_2iN6JJXFAYIA1_}Qq=wedUFbp1rsG^pqxBBl{uG4_J^N20*YQRlU`lP zVBpP|VMwX|S0|#8oVI1LN8lPTugLw`MBdih*<Vw*QM#}>@+S3d270k?7ikRx15HtjNfE6Lo~a)19X0D*44 zSK9bW?r9>P>SpiH0TPBeJ+z1DgB8s)wvBJ8448tLdhD%NSyfk=Z9r-IF&JYU&>YKo z?iA*SGnL`*kc*m|(*9%HC5kA4s$1w2LQ}aY^d!I^6Wf1lL2C;kM3MH%K!*2(O+L6s zO9qWjU;*X7{5~?%pS0SeOxgpWcZlsY%MBKkCK!%XpUA9M&09M_7$E(+3;C@TDj7Pt z2qRFmrIjQTiaR#O)(2!yhJYDKfP+J-&^_Ck8fq@n$d6R?Ya)meISCm=?t7(ly#@6W zeishJ%9mW`h_Qv!jo_pFZz`-31QP{s{`drXG@vm_W1u~CJti*r!I#ljJH_S3cpoU+ zCsBZ+fdv@S=L=nh8u^;IX`%~3_!O9Y>76I*mHf0p6o}frl-=$hOD{44zyTP+=W-}K zllJFy9lW4dS=|oHf2M-(DHeDjyxLUe!TGg{Ek zA(L}BkPi#CFt`+Hx~`^&=8JDYP+tCLrAk;lMb*pwc?-M5%|Ff@Gb~{332=pz@H0b} z7_RRxml7suwe_Dsnpw~@cV;jjGSypO&I-*lfb7*mPatfkQs*FBA+MQ|xK(Y)M>rwY z;G50v65Tp1YB)SxNgtWu)eg4on*i36W*_$bFecY=Hf$oAm?QYow5mA$Rll}VO! zUzt=rm(vQnj#j#+T!LHc$aklT8H|jKtW%)TlMn%lm-`vc{(ODC`KwJpZ?2&z;}|$a z{gI5A#}c#n<6AhCl9*=+-D0W-M`O*UqiOK*&GY9%ihYc;6? zqKeJMHtD8bJ;6Nw3R^r$C_j7vO;s+Cmry24hLpDj?FT;$S>EFhJjvU{65);B9fm`0 z=sD{)ddqT>**YGG(=T?9F3FQK{&{H1b4-VK?ed}xYySCwn(ofVMBy(6)dxi;Q!D(` zGu{8QWF7L1G3-~FuPEaNH+`u8?V{cZ0A7!(DkU$)VI zA*&bwgX15=JwN>EFZ$OLawZid`AaCps{$~1UEE}m>MwE@1e(yweTV;xoY$X_^Yuuw z``-{rK?P_s5L5m9?_IB-kn;og2HBrDQ6l!K$^Qw%KvX`#7v)L*4-)?RVX|E=S2e?+ zNUNA05acHSvF|nDvw>21F{ak z0H<&;up>lED~*iHnE9RkbtCQ7-;7xxgnk(@aO{6lbNpi-#uXU6Vc079@)WHcaO8j zVE8h4;fedXuWQXU=Unr`!%G5ySzX$nr9|XfYtnKFsLi;W;~#p(*{|IzbqM=l0K;1M z5!Ofq)d9{F-DiUy{jcQARtNJ|PloOqCIq76wRZB^O$s3jfB4zgRQpBPDPj^r&kH;w zz6xS(Z*R4ISX@pQRL)VopXKq>f-o48N4`O>%2;-#pWGY-yf^`THoGtR8s2l|RWwmo zWV4+Z)m|7dG4{#Jlx-kV6U}@rM%|CT-}mY9V@>^&odGps((iumw|=)y`0=Pz#toIg z9$`}oC?Z6%mm-f6R#sSbD;<1cGE5W!L5Ds*9AGBD;gr>{T3Xe59i#AO0vl6HILR|$ ziQ1vd{r*KfTMh85dFzy8+ZBjdxdn+0UTLmF#^e#zqg|^gY?DiF(Q|HBYf0gm^-R2-mRk_a*=8)csW-Fz^$VH560}>ItGVlq@JX3cU!Q5@iJW^yh zBl<`pPdzi>VL>HyD$ljINc zVOq7hD=8LfPZ8rnXt-3YkS22ZzzB3B{toz7i~n$Y>8H+>69JIUj8!vTzEA4j>UHn# z{>!pqm>@?#r!R2|Y9|vD*1vTHXb3%A8gWLT3(Cy5)~K|@kWkQak;JcG*FsD%BF2^^ zaxreIkY2mTsKXqdK);0vCeFL6uXNu(*wU$a^kX`^QW9-v4%Qp>Pu{KX^@+n1+^Mmw$v?M{Yv_iQu&igj~cMqJAkhl$Q<=^bbg2 z9_IEvIY6y2D~S1vIcABGF)5XZwm3K4X#Rt8;t?mtv?UBY`|{@IMIh#x6rdF|gA4GL zGp!}k>@76P5qJ5ZTxczMZ!{l{TNgn)a8pZMC=KAFkb&(#&R7Uu?!}Nlve9JaZ`nxJ z6s7h&#A;bwU!#hDLh#; zVuJq>eo~6{j>t^_lrFXJD{WqTT6n+uEe(gvE-^xH*Q;nfaCiTixv8bvW=w-~rS5c3 z&u7(Xvd*X4V+x%5&NDb1y4N&b1*NnSo$uQiZphJuWZI5Aj`KRYB__I(2PO;!Rjz9k z?=&dLM1tM+?&YM-*H07w3Q98c9do%Xr|0Ij9pud7h9~D|4+P-rA!>?WrCl}WrDawN z`CPPF2sB-IF!r8IB3RO|Nt|fh(=UNR=d*tTqwuU3y^i?XPnJi}F|05qF>p{Gp&Ob8 zOSFI`G0SnG)x6HQDI{gt@ny!9jTrx{i9pe{+zI-2{tWoUsCF^$J4Wxnt4tR4sF@2o zykGCd2Z0VAFr$T<9@3_odeAUU;&3E;EDU2D_iT|0i*^YD9(>pTVdxqB1i)&((VK7y zq+etQRn~Kj!Asw(e~#;Ed6uaGibV)Pb4 z4TRgF`j&;N4rghlU*G6^vj`W+%>w6~(Vo;}{LhiaFC?{Qt@9&Dxe{TCcERi!M;=d3 zUFTZ2_TxzKoafbEccJ(zHsMF2N=H8QKiFU+sjqI4G%OhRS(ULs${)741HB?5l|^a1 z^x@Fn?AgiBnBEgaYR#YRqF4=B=qBGsDbLQ!ydo_bhLA}(Bbj8$-v^gO-UEBfs71?* ze@H?A@dMNrn}0v}zrXR{uSd{$?{oJXd}f`D{8pkI>~}fUYUDZibN*lPg5u4>Q_b>8PlKWq&EK?$A$1q!!r~mQ&O-gudjS+V3{8(t!KW2#?uYW*Hb|wj} zwd}5qm;oQh>-<#(X1kO5m0rRwtCg+#@@EtFfGEKu5Nj~=(IM1Gy{!!fc$5=4u0jIY?r7c6 zB|j$&AjG-zx%jg@cUQN8s&0QYO-Hav8T^f^n z{{*PW1SsvwmX?v)Ed(P6TMtU4yn!aWNZ+Gb<#l?l>0zk;hBq$%Yk0GXC+SzeNzBbZ z@LB<{BUP|yn_)A)O^*r{jp_!S$*knPciPu<%d8SA*0!F~#r z&6NeXGg_WKgIVoV6fc+;AF4I6LNIkDR&t)8v)xA}$~L;pp_AdQs-6MFi&eNHX$V&< zqHW}CizH`|_;v7FI5gqnW$J6PF2A5+cJyV+T&&~3{o|KJjZi&%j{ z*d1&%Il z{y>keZ0&`SbgeWP62E5^h4}wT`uArT5zof?jZao+BL$Xam!Wv9s9khJolY=cxyRLib70$Ihq-c%@ zMmmp6VP3gg_eSdlo0A@61cl-j zTdk1rjDJCK+tfUSkIoFZT4C!K3i;zHfFJLb1u)g>lmybKq|EAi!z$o>=Q*Drd(OI0 zsnHr2t%kXH-O~qv69>UcovTCagn3L)!S}Dntd_qRCR^)Y6;HT0hMkxAmYq zsFYC+tD2P##(8(%C7x_H;ki|}o+skqvdpq#{ZCE!GQRhy;yb&ks#dFbv{u#3m$k!r zIYOeC_(j2ysQKZ2J+CagdQ{UKzBhl*#3;s&q!zokk(o)4e1aE*j7;W!NoUFb4$Y>F zRQ+3AojW^UA3TBKRqg57>Z`&KoTdtsjgK7B46z1-Y1XW+a5pB-<4a)Z)OG#OdtBaV z@-k^c6khaiff+TDm+Era?gi-!?{4H%iW}oMZ)=>&4S=rQVmd)4x{FuWdg*aEm>F`- z(yQu=jhl8JzECLr@Ia~C$7C}qW=7#f6d8HxC)5)juQ?*WM3u{cJ0Cbw>X0_N3$cwOSlrm8#J$uEiW%({^97= zi5!}V|JbFb9ZrrpXVoD$0zi7a2hCUallqz%f5MHm3vDtG<|<5$vM~8^`qR!Og22!D z#kX71!F{=Y!~Y?&O~(|pI65;FTRGxt9&^VUuVgV1;^NUBX5HfeybR-kYhv~GWA9tm zMY7qreURwBR`;&MX&!X!El3u+nyMY{D zRqQF}92ygP?4+Z%-yrm-4WFeu*Tk7P^52)py2NeCe`3{GY50gAD43{Y^+9xcc9%9( z2>U%`o^e0QkX6VJ%=K!cW#c|AcHc5tT9|uSZELvX>a*F_cPvxih7=wD3suB+);eeO z`pqJT2127JNTm_C+M)Gc{K6n)Ar7u*S~AvYsu-`sr4uVXWRY4dY^h4!zLpS?nlsDu3g{)7@TrwI@QuK4k{*iAU@MxD1= zJ&ZtM&8b{pCpl*XV54`PXmpf6&X2e%V(5B!yBG1zuNYLKjhiND7}tBG7SdZ_oZwjgfz? zcZ5$Q5HNPQApMzk!MJjv{zo&&``!9PNyC)xv#0wI=1NAWfcZ&+!qx>H$kJ$u>7Oj& zKg>F<9r8m!vBKBC+k~Z>9`6<0eyjBmXv|>!I&WRKAJgQUXaM=yAm>SQce={8D_;T# z&6lAeAAHrHF&5yyG`}&*q_EbUw9$7SOGI~S`6D0N_!l_hMcNTKeec2$`BndoeiV$S< z23q;|Rzqwb?yJ0(m6gRn`vtE0yaT8R9YAlH?XC_%AnSF$qTMV&l(#GF?gL8{L5|a3 z>~rh}-ho81J z?Z!hwp~`KyA2mOt#|!{2e0F}JlFTgyZmHbni)h{l5wu1mDhPxx-6&RSJ<^lB_s~2% z0&Ewo5vbWFM%Vl`^Y&1r#vr|=YavFWa2`ljM(}UlK}PkM%{l@}vP!VQ`tQo5LTbar z#t#n(PsH$x_t92Is~;7y<(!Ihi=muh2O(@=S9T>VUjrCj zRcPD#t81t-&9c&9KT_NbY=?M6o;Md7=2mlN(*$`6d2n8#P+ccLM95q*qc+|h1q28w zC2}|NR#AoW=_M77s+z|5d2GG#*FHfI zhW3^r+uEg1lkDgojaZ8{76u28TN5Y&ti59UFT5d!03qX1BB*+CpChsXIk9!^f5CvU zHmFoA-1;poxw5C?VJxe|4+RwgX%<`-Hm<#vJ}E5Xm)Q#o!f7Ip zRI}C6IRT~J?aBH*Xl$&3d(*PyD%oF>9k|l}>bOhHS~mbs9{)9e`MDZ|jPT(U{_O2f zD4NNRN2oL!0~4__kt-Kwuplh}F|rda5R<%@3>H0XDk1e2gr3mq_U%^ulfIN$l_L;N z$P-^U3U}IcMb7>~C$PLC{Y+6?Z5=gqnQu{mCfmZXpn`3nbLG`zge-*U;2|4G#wS#^ zLJ%w~K5wJnMMah3&!+PLfAX^{AOGSr=3Bgi(~W~6xI&>zDBvh4sK1ULuysoMZRXRb zs@5GyE?(0TmA#bs#)M)q;jV#(;{p0FGJI-`Tzin(|8<11ewvs;WcI@qNy?0xTm|zc z+lyPR)C3X8)4!9=#6M-frEHcrgiRy?OtmYlKQTgY+T18a**0kj#f9CSw+>B2&G0P) z2Q^SC{0oy^2(rNFMnBR-vWy>X{XR+}vCZO}3ICYZWFAu&H|oEo`6;NI*W&gz&Ma)A z?%#!3wg*Cjtp{SL&o2uULpEDYn-$NBVWmSua-43a+n1BIqEDhZOO!Ln^@zf4`ICUa8_PQL1;Q?-XugUQY_2 zg6=*2OPhb~uT)_3yNr$f3XFm*l!C1)Bto&8`J4@%epm6Fd59K3yfgA zR|Kodv-M$cg^57|VyaaU0<^&DVzf@h`D5W^6hl%_dFp+##c_DJ90gflqz|W0QeOA!lPcf^(#BYva^3}uStsiG|j@CB`qp|lShPnG~`jUnQe zQglV7qT}Xn#{=n8z;>J#A$?}w(qrrlL^SG);GrAxS?QzuHd2&MXZidlSl&_Xhq{uu z?mqnICYQ0wFNJEzSuq7laFVsbIXNVXKtS~ra&ic(PH{&4*#$aai*J`%-O1Da zkWI|0UjKY(;YO#)YBo5qIv+IvC}PZhtS&gNXxR=7-(ZoU;Wj8#eQ&#eSx!Hi_Q;8l zYZ{jXr<_U19szgM9axbq4R;M`sT$Y;)V-xDYw>viT z<57WWy6+KiL-V`hM=K1~2lEjdpjL5c|A>{rRhoJ%Xj&XaiJ1bVSMiMR@iku|j4N>h zp!1SkVQKTv8j=b`8v_m#{|cAw!l0%aPFT?s2ElC&*kerur(B-VbRHl3q2OZdOFag3 zgiWOi zR!o^!f3LE}2=qWIJcZl;VhqVfr>rC@e6giVnuwD5z5@ZO9OiUJ^L6tn$W6#dfVne(&OV*!wYzHOwO*p2 zC0eO4h5&8KUANE+;C*OATps~_bJ0MCRA67IyNBpi$j-N8?jPZ6<#|H~BQ8jo+GY}2v1y)CCp30Ywt>oYC zlyV`{(<0NWW1H;RTf8uoTF-g7d|+P<}A%xv~5L zpLY}K6R1cH15)JEdk;r!p^?)N$2`PNK{Ms*s!$tfX_D4ylu`5^ctkVWVckALHc5bq z@e-yDLahKM-CKP6Z7@%>2XXR+7RS15GNeXiX5#juYQ)=d2NGoxN1lS7JBCPJ-QyEW zcaVO3ew)Tinp{MC)RCc6?e=o;Lh!7PKAm8X-`(7gT`xWNC!N*8R_$wdwH?l!=`{nG zZd~T%tl0)-h*XyN7oVQ@r{@<&8}N|X^7lf(QS^AfY4N9(%!K1J8v6vF#qIc{Kloqy@+sm)ZUgS1cA2SCj~o) z`_juc={JX~H_9h2Pe$Vf)wCR^I(jnH(B){$eXjIv6`b*YW+1xGKs@)xqAFUNN(Hr}oZSe*@;w4Wb zYE(F(tbhG1O(!)kIy%e`HhtqA2oK=ww7<|+Vi->@pb8P2Z*X2)a_Dzt?dYkNpl4$eiAJ)7Ntdf$& zq!BtLPhzDnxLO+n^s#S0AbDJt>;} zt8L@>*mWt9HAvZk^kfKyRXu2zWspCl_DxHf$^NQU!gA9BRKeuJuw+Wl!`bNTF=(4F^Z2W=9s1d^9v z+9H;a#=OnQoz0ug+EWC2P9=#4=vQ3S8K3i(Fef!Pi5a9=({^$P#s9m58Rd;mm^dlk zWHU#@;Xv8iD^t%b4}cU56(Dc#aDIZP9Yjvn?6tE((8;|!n4>*^`%#Ji1>?>vFEqsq zAd81ABNZv=M)~p#0mo42HfEM2HBCH@68;0l?_o~(PeHV z$}N8uOS<*4DpIf)Nx=Q)Wb*e86>@W*>$c;AcowJT1lJ<#Jftl=jkB?ijnr6KpV3{y zAblzmFh^o6kJVZ_sqzW6tCp{9C}(@#v5{e^<0YSYH^%O+!k=p3gvm%ROGruzqP8j% zpK4xwwR!k!ytJC7_d=IZE(hK@DY%kZulHzDr#n1>g*;bP_#5NGhHzR|Sm^7TPmRja z5bgGfD%O|?I!F^+tuJ(h#Vn6dNodeDNi!rL6t1^6PW!fZSISc0pQpAD1rA3{@bO=MzaLLd78T*O2F! zS1ij=z1>+N;JTWnTz%g#GQ2|P@oS5|?S@o;>xO`f@|JW{r>au`3PZnT*l5Q1r~Aid zDM}-$JdM<=>j;`AU5z`d=N+Y5py0@sI~#2i2`CPmsQyuB4e$lSCxdGz%+nnY{P(0s z>+JrXVn34b=6zpq6W;V#(Dl2RhB9uFN`>1FO;q4gIrfb7jS7DJO-in&zpRaS5rzTXk{|O@ycmc?G z7bSE;Nkbpzmj+tK|JnDnuK9mDX}jY!WpZ}`=b52Kf${=QO2zgU^Sck$hz69{Coodt zFPkg=K%tHb=N4uDRZU0IZ{RU5x#<2&rEY_kg6}hLM@3!d`6e18NiWT~RDE&iGVEZ# zzZ5BuFe9_Xo?1=Qh_WoIWi5xshqSD1T_gJae|3JL5NGMFf~KGz}3O8xh0 zKwv;*nKQJ1kH+@G4^=*x;ZEScXCx#$68!t@^y+h{jNEKgc@)Hd-$HDC->1Ld3dq#oQ1!aj)v5^EG|MI#x%;B}QJ7PG4D}FG$ zIp*9eW;=A}ZdtGRad#r;{d;@zcVnN!P*l05>Wvm{LmyYK-J!eeWh4AngT?pV##(Si z*11Jy{ZMQ+%0|i|^X-c-lqKcbLJHD9A4DCh73WMBSG8v-E{o3b-phPo*aeImUnYz* zp$+{yJ=OynHL9Vv0HR5aone)^fr2{GD{;1-qh0j_^2jHLbuF$;K&l%1?zFJWiV+xQ zI9kayLhqpWBwV^16#*AVvJtT_IdxrIuUd? zYT+5iARO2FG0eJD+QGojI=Fhv0YwykInua7QMVX(GhZ`D)t}GiG4uh)z|z`457Z(w z0;HetY@Zn7u8=Hah{f=4pp|f#eIwwtceWnMSEaW$Y|FkRwX-(TD=_KM)VBu)eoH_= zQp$a$C9p3|M~iMNdO?C`<467x{Q(HI*T3qMiyM{QXjcy4JXnuueGtxjY)W;U4`UhE zP`F~InXM8g)MUW?`=c!0CQy{cMbqi7kH4l^NOQ^qb8Q>NKU@rmXh8gM@tKL4H#%24SbuD29-ow4(|zBJ zM|#YR-9UN7_AcM#6Sx=;rlI3m|MB>&`V_EDCQS=l)`m^hx9oDz5-3mv?9bjTh2sBu zIGmp{1ae_>ZA&U3^4CqLP%yo&Y6yz>vW-t$zK&`v+xmV2N_qd5w*bEFWGKyBFL*w$E+}@QB{s>}kd; z-;~xezZ9`FfG*2U6U2LVd3CtJ8sKO~0sQh_3#p;({%ah>rjVGsQK}?&}*c8{>VRZ$rxId)KN%OQ)^fsGyGo5W& za~QZKc$oQO27@6|9Ki>Zcg3O02!%`Cn7Z^$<^@mSabfj$isuZ(fw3RwLMR)5!GQzD zq7yD~aGX9q9YUjd3Bw@$-=vQ&kfxDHhfxvj$9+zhm;r}0L0R6vt3p5@hGJnv#`{3B zGnI#LH{IFZy8o5giAzd_(rPo}xQSS!HC*)7GU3sLBVNA<8>z5O1UxVC6<*Xu>MfVC5@e$}}b0dvgGjN&#cl1SMU)UMPXs{MDl{ z;=RjM+CMY!hTw6%PvOhSsX_6{_dPYEe)8TeMvB@rgKN;?@o_2~#4$}7hBa=iF2iA@ z-}H>K$zS5kfs2zz_y)NiyO<@MP1o%OxcHpQ9gEjDp zw!8_P*uU2}kHs5qW8h!<*q!qYPV%DweJZuC`fd=n+C%w5lpCDC(C|o|jPO;0i0oj` zaY#dwuv_|ua=P%`(NSsw*#2;*2a4QLlpchm;5xa28L++MzZ`HNyWW8)wHZ}Jiuv`k z4cx5Yt!LQ{d6*|q%jNn*@ zMihpteV^r!H}I#8@EPZb7lawpJoS99#c|(AvwK2U0m|^PdFv0TjN()|hG0oF#YcUD zEUq%<+CV@mLr!`0la@LX2u$=XIkM(8XNq35X_Rg4`F(>l@%qmnn~z&c0HKOeg@-C_ z{&Fu=e4*)agx@<7wl6jD`=hvm$;d0)7+7CssCAv*ofEutHqOg+8imVEM$s$*x@^JE zm$f$&Ur_(rELS94j1nC;Osq*Q7 z^yno5*G5d1Am*+C^liEKV+h{lvUWtMk|=TT=9UBLZr4Dl4Q9dE(VGRtOE2anQp~D% zaO}^JY8o^W9E8yVago;?ctN8gnC{f8tXVkw*B9R|ghe+0>_T+0ybtb2!zkMI8Z!oI zvV&yvo9|iqRPaTnxjwmNuT{0RcA2w1^X-=5-dfO4Z|;yb&uU)#5T$6sj83y}5c?uL zlvyla{izSFJt`Mo09tPc)TGNyKD+~rsdpaGyuUBghQL5ZW=yd{{sg3?Fy#)1F(zH} zy)%toPun!x9f>h{@?D^J@H_Z#0`QIRN1mN5OYDJLD){2ZO+VV($%)VH>edB}Bey9G z&?oo4SFscYo?O&Fa>uWX0RsMdkjm@DjBjm%y$Xkf`s2n^2~*bV(8E$OQx zzCaVDX#Y}~|(ba9;lTx*#u7BbJ{e5nQ(byO5Ae&c+Jxirk} zOJAZ+(1NfMZ6$9NJ$slg=rLV<=%ea%@6vv3mvQ{+usiMrQ7(!xzE4ecX37(N_j1Ex>uV1 z?qDnT#XRD48O09<1kF_-Evke=m@Yvd8Zh2zQS?!FWJXuA*p#bH_7Tv(UcbvXHyMa0 zPFAB~!`_9XC{6Cd-5jolr3@J55f$M|~m9djB>!`}#MC>YT^ zI6Cs!O|EG1F1(+4o4XRq4YLH6n-BU-9XYa%2+v|Zl`#-Q8o=%K?V6|$Y>a_ll~`Ur z2tt}ydX62pbV{P_L45? zobrmw8<0p-;?+?qld2MIR*Ta}{I7A{YW=}(YHrmO!^0n+ZedZ2+emZv%^extc4^CdF;g^ z9W^>T@d*ZBjsdsHYRO-SLkaMY+W3=ImCjfLAE6o(RRI4t0?rKlBT2&*qFu6X-N|tA zW91Bk-s6O{10}LBRF!RfqlR@NM9&%xB4n*BZ#KN-Y#&061#5L$EsSG#FLz?q8%y!A zUIayYmNX{@^R^ErQK2k$jZL{?<}ep9*MQLVD3wYvm2GLbO|5lw5D z*y&FGCCh7{{&uZW;i6b*i{4TA$R1SGA9^bc=$4W@mCi66xmT7=-LW@44?HOj2RpRT zr0OZi+^===IR}+*J>kA}ITO{?iF2C(jbtoTWk0#MgmH&1-S=%IqN`$zlB7qK|B{jW zyHfsc)Rq`xpWrJU+DVoDYqR3yC6O5(s>z-b{OQ&F6a4&8Ta`EQU9k{bBYeePhrUtC zi+(lcyjROdh2~5%4`mSC*7SHf3^uQg!kC@6TIkf^&LD5>*=+-Uxex%;2^2zmfa`&%n45 z_U{T66XM6#>tIs9vXeS*g8x5Vo_7Fat56ajCM{O!9!EAU&TT)SUY+Idu5!+G6v$5Lb|Ueg9z&I%9=${MRRV0sbJ4cfkR9WDXw z=&HprSRK=#8xh%A0)afNbGSfn#9bazrLD`{nfs%xWe_h^n-H1*nFGxg;TJ|56OZ0Q z$iqYs<|A#ZBr+{Hkjx$g|56HmE7=h%7y=zNfD^%9!Wm?HfI1bHwacTR4Hd

)2Tg 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 literal 0 HcmV?d00001 diff --git a/tools/generate-workspace/src/cli.ts b/tools/generate-workspace/src/cli.ts new file mode 100644 index 00000000000..d58937b4ef8 --- /dev/null +++ b/tools/generate-workspace/src/cli.ts @@ -0,0 +1,118 @@ +import { findWorkspacePackages } from "@pnpm/workspace.find-packages"; +import { findWorkspaceDir } from "@pnpm/find-workspace-dir"; +import { writeFileSync } from "fs"; +import { join } from "path"; + +// Define ignore list and name mapping +const ignoreList = [ + "construct-library", + "@wingconsole/eslint-plugin", + "generate-workspace", + "bump-pack", + "@winglang/wingii", + "@winglang/wingc", + "@winglang/tree-sitter-wing", + "@wingconsole/error-message", + "@wingconsole/use-loading", + "@wingconsole/tsconfig", + "hangar", + "@wingconsole/design-system", +]; + +const nameMapping: Record = { + "@winglang/monorepo": "ROOT", + "winglang": "CLI", + "@winglang/compiler": "Compiler", + "@winglang/sdk": "SDK", + "examples-sdk": "SDK Tests", + "docs": "Docs", + "@wingconsole/app": "Console App", + "@wingconsole/server": "Console Server", + "@wingconsole/ui": "Console UI", + "vscode-wing": "VSCode", + "@winglang/jsii-docgen": "API Docs Generator", + "wing-api-checker": "API Checker", + "examples-valid": "Tests: Valid", + "examples-invalid": "Tests: Invalid", + "examples-error": "Tests: Error", +}; + +async function getWorkspaceDir() { + const workspaceDir = await findWorkspaceDir(process.cwd()); + if (!workspaceDir) { + throw new Error("No workspace found"); + } + return workspaceDir; +} + +async function getWorkspacePackages(workspaceDir: string) { + const workspacePackages = await findWorkspacePackages(workspaceDir); + return workspacePackages; +} + +function getFolders(workspacePackages: any[], workspaceDir: string) { + const folders: Record[] = []; + for (const pkg of workspacePackages) { + const pkgName = pkg.manifest.name; + // Skip unwanted packages + if (pkgName == undefined) throw new Error("Package name is undefined"); + if (ignoreList.includes(pkgName)) continue; + + // Use name mapping if present, else use the package name + const name = nameMapping[pkgName] || pkgName; + const path = pkg.dir.replace(workspaceDir, "").substring(1); // Remove workspaceDir from the path + + folders.push({ name, path: `./${path}` }); + } + return folders; +} + +function sortFolders(folders: any[]) { + let sortedFolders = Object.keys(nameMapping).map(key => { + return folders.find(folder => folder.name === key || folder.name === nameMapping[key]); + }).filter(Boolean); + return sortedFolders; +} + +function warnAboutPackages(workspacePackages: any[]) { + workspacePackages.forEach(pkg => { + const pkgName = pkg.manifest.name; + if (pkgName && (!ignoreList.includes(pkgName) && !Object.keys(nameMapping).includes(pkgName))) { + console.warn(`Warning: Package ${pkgName} is not present in ignore list or name mappings. Please check ./tools/generate-workspace/src/cli.ts`); + } + }); +} + +function checkIgnoreListAndNameMapping(workspacePackages: any[]) { + ignoreList.forEach(ignoreItem => { + if (!workspacePackages.some(pkg => pkg.manifest.name === ignoreItem)) { + console.error(`Error: ${ignoreItem} from ignore list is not present as a workspace package. Please check ./tools/generate-workspace/src/cli.ts`); + process.exit(1); + } + }); + + Object.keys(nameMapping).forEach(mappingItem => { + if (!workspacePackages.some(pkg => pkg.manifest.name === mappingItem)) { + console.error(`Error: ${mappingItem} from name mapping is not present as a workspace package. Please check ./tools/generate-workspace/src/cli.ts`); + process.exit(1); + } + }); +} + +function writeWorkspaceFile(workspaceDir: string, sortedFolders: any[]) { + const workspaceFilePath = join(workspaceDir, "wing.code-workspace"); + writeFileSync(workspaceFilePath, JSON.stringify({ folders: sortedFolders, settings: {}}, null, 2)); + console.log(`Workspace file written to ${workspaceFilePath}`); +} + +async function main() { + const workspaceDir = await getWorkspaceDir(); + const workspacePackages = await getWorkspacePackages(workspaceDir); + const folders = getFolders(workspacePackages, workspaceDir); + const sortedFolders = sortFolders(folders); + warnAboutPackages(workspacePackages); + checkIgnoreListAndNameMapping(workspacePackages); + writeWorkspaceFile(workspaceDir, sortedFolders); +} + +main(); diff --git a/tools/generate-workspace/tsconfig.json b/tools/generate-workspace/tsconfig.json new file mode 100644 index 00000000000..b5381a09482 --- /dev/null +++ b/tools/generate-workspace/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "ES2022", + "target": "ES2022", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "strict": true + } +} \ No newline at end of file diff --git a/wing.code-workspace b/wing.code-workspace new file mode 100644 index 00000000000..1bedc45849d --- /dev/null +++ b/wing.code-workspace @@ -0,0 +1,65 @@ +{ + "folders": [ + { + "name": "ROOT", + "path": "./" + }, + { + "name": "CLI", + "path": "./apps/wing" + }, + { + "name": "Compiler", + "path": "./libs/wingcompiler" + }, + { + "name": "SDK", + "path": "./libs/wingsdk" + }, + { + "name": "SDK Tests", + "path": "./examples/tests/sdk_tests" + }, + { + "name": "Docs", + "path": "./docs/docs" + }, + { + "name": "Console App", + "path": "./apps/wing-console/console/app" + }, + { + "name": "Console Server", + "path": "./apps/wing-console/console/server" + }, + { + "name": "Console UI", + "path": "./apps/wing-console/console/ui" + }, + { + "name": "VSCode", + "path": "./apps/vscode-wing" + }, + { + "name": "API Docs Generator", + "path": "./apps/jsii-docgen" + }, + { + "name": "API Checker", + "path": "./apps/wing-api-checker" + }, + { + "name": "Tests: Valid", + "path": "./examples/tests/valid" + }, + { + "name": "Tests: Invalid", + "path": "./examples/tests/invalid" + }, + { + "name": "Tests: Error", + "path": "./examples/tests/error" + } + ], + "settings": {} +} \ No newline at end of file