on main help sign in
213 files changed+14218−7186
since splitsnapshots
unifiedsplit
.gitignore+1 .vscode/settings.json+6 .vscode/tasks.json+13 README.md+47−21 base-desk/lib/agentio.hoon+4−6 base-desk/lib/azimuth.hoon+9−9 base-desk/lib/azimuthio.hoon+3−3 base-desk/lib/bip/b173.hoon+1−1 base-desk/lib/bip/b174.hoon+2 base-desk/lib/bitcoin-utils.hoon+2−1 base-desk/lib/dbug.hoon+9−3 base-desk/lib/dill.hoon+94 base-desk/lib/ethereum.hoon+28−4 base-desk/lib/ethio.hoon+3−3 base-desk/lib/hark-store.hoon+22 base-desk/lib/jose.hoon+11−3 base-desk/lib/keygen.hoon+1−1 base-desk/lib/language-server/complete.hoon+4−3 base-desk/lib/language-server/easy-print.hoon+3−3 base-desk/lib/language-server/rune-snippet.hoon+2−2 base-desk/lib/noun-diff.hoon+213 base-desk/lib/ph/io.hoon+238−4 base-desk/lib/ph/util.hoon+25−12 base-desk/lib/pill.hoon+500−18 base-desk/lib/ring.hoon+46−45 base-desk/lib/server.hoon+2−2 base-desk/lib/shoe.hoon+72−36 base-desk/lib/sink.hoon+26 base-desk/lib/sole.hoon+24 base-desk/lib/sss.hoon+445 base-desk/lib/story.hoon+88 base-desk/lib/strand.hoon+1−188 base-desk/lib/strandio.hoon+171−14 base-desk/lib/test.hoon+55−2 base-desk/lib/verb.hoon+88−11 base-desk/mar/belt.hoon+3−12 base-desk/mar/blit.hoon+3−44 base-desk/mar/css.hoon+25 base-desk/mar/hoon.hoon+285−31 base-desk/mar/htm.hoon+2−11 base-desk/mar/httr.hoon+1−2 base-desk/mar/js.hoon+7−4 base-desk/mar/json.hoon+4−4 base-desk/mar/json/rpc/response.hoon+1−2 base-desk/mar/kelvin.hoon+16−6 base-desk/mar/noun.hoon+3 base-desk/mar/sole/action.hoon+3−1 base-desk/mar/story-diff.hoon+16 base-desk/mar/story.hoon+65 base-desk/mar/tang.hoon+5−5 base-desk/mar/thread-done.hoon+11 base-desk/mar/thread-fail.hoon+11 base-desk/mar/txt.hoon−1 base-desk/mar/udon.hoon−5 base-desk/mar/umd.hoon−4 base-desk/mar/urb.hoon+1−1 base-desk/sources.txt+2−3 base-desk/sur/aquarium.hoon+18−5 base-desk/sur/bitcoin.hoon+1−1 base-desk/sur/hood.hoon+283−197 base-desk/sur/ring.hoon+1−1 base-desk/sur/sole.hoon+2−1 base-desk/sur/spider.hoon+14−1 base-desk/sur/sss.hoon+39 base-desk/sur/story.hoon+9 base-desk/sur/verb.hoon+37−1 bin/commit.sh+24 bin/get_glob.sh+19 bin/install.sh+82 bin/make_glob.py+208 desk/app/astrolabe.hoon+298−17 desk/desk.docket-0+5−4 desk/desk.seal+7 desk/doc.clue−24 desk/doc.toc+15 desk/doc/overview.udon+26 desk/doc/usr/astrolabe.udon+107 desk/doc/usr/azimuth.udon+51 desk/doc/usr/comet.udon+10 desk/doc/usr/galaxy.udon+36 desk/doc/usr/keys.udon+63 desk/doc/usr/l2.udon+60 desk/doc/usr/moon.udon+8 desk/doc/usr/patpee.udon+104 desk/doc/usr/phonemes.udon+45 desk/doc/usr/planet.udon+9 desk/doc/usr/sigil-input.udon+27 desk/doc/usr/sigil.udon+22 desk/doc/usr/star.udon+21 desk/doc/usr/urbit-id.udon+116−5 desk/lib/astrolabe.hoon+174−29 desk/lib/search.hoon+373 desk/lib/state.hoon+21 desk/mar/astrolabe/point-set.hoon+13 desk/mar/astrolabe/point.hoon+3−3 desk/mar/ico.hoon+12 desk/mar/seal.hoon+12 desk/mar/webmanifest.hoon+12 desk/sur/astrolabe.hoon+56−3 desk/sys.kelvin+1−1 desk/tests/lib/state.hoon+59 docs-dev-desk/mar/toc.hoon+16 flake.lock+27 flake.nix+73 install.sh−44 ui/.env+3 ui/index.html+7−3 ui/package-lock.json+2175−5564 ui/package.json+24−10 ui/public/android-chrome-192x192.png ui/public/android-chrome-512x512.png ui/public/apple-touch-icon.png ui/public/favicon-16x16.png ui/public/favicon-32x32.png ui/public/favicon.ico ui/public/sigil-example.png ui/public/site.webmanifest+1 ui/scraps/tirrel-graph-main.js+198 ui/src/App.svelte+65−8 ui/src/actions/doc.ts−39 ui/src/actions/docLinks.ts+26 ui/src/actions/symbolPartClick.ts+27 ui/src/actions/tooltip.ts+40−8 ui/src/assets/astrolabe-tile.svg+23 ui/src/assets/astrolabe.svg+206 ui/src/assets/up-arrow.svg+1 ui/src/assets/x.svg+1 ui/src/components/CollapsibleContent.svelte+4−5 ui/src/components/Doc.svelte−17 ui/src/components/DocModal.svelte−9 ui/src/components/ExtensionWindow.svelte+25 ui/src/components/GoldBadge.svelte−21 ui/src/components/HomeScreenTiles.svelte+42 ui/src/components/SearchBar.svelte−59 ui/src/components/SearchResults.svelte−68 ui/src/components/ShipListing.svelte+37−11 ui/src/components/ShipListings.svelte+19 ui/src/components/ShipView.svelte−262 ui/src/components/StarChart.svelte+233 ui/src/components/ValidationProblems.svelte+3−1 ui/src/components/buttons/CloseButton.svelte+4 ui/src/components/buttons/Hamburger.svelte+5 ui/src/components/buttons/InlineSelect.svelte+16 ui/src/components/buttons/ToggleButton.svelte+11 ui/src/components/common/ChartLink.svelte+11 ui/src/components/EthAddressLink.svelte → ui/src/components/common/EthAddressLink.svelte+11−4 ui/src/components/common/GoldBadge.svelte+10 ui/src/components/Sigil.svelte → ui/src/components/common/Legil.svelte+16−7 ui/src/components/common/LoadingSpinner.svelte+8 ui/src/components/ShipLink.svelte → ui/src/components/common/ShipLink.svelte+2−2 ui/src/components/common/Sigil.svelte+65 ui/src/components/common/Tooltip.svelte+37 ui/src/components/common/TooltipAndDocLink.svelte+14 ui/src/components/docs/Doc.svelte+50 ui/src/components/docs/DocContent.svelte+37 ui/src/components/docs/DocHome.svelte+76 ui/src/components/docs/DocLink.svelte+26 ui/src/components/docs/HelpModal.svelte+25 ui/src/components/extensions/AppIcon.svelte+61 ui/src/components/extensions/AppsShipViewExtension.svelte+56 ui/src/components/extensions/GroupsShipViewExtension.svelte+15 ui/src/components/extensions/ProfileShipViewExtension.svelte+52 ui/src/components/pals/PalStatusIndicator.svelte+191 ui/src/components/pals/PalTagger.svelte+40 ui/src/components/pals/PalsShipViewExtension.svelte+34 ui/src/components/search/SearchBar.svelte+152 ui/src/components/SearchResultNavButtons.svelte → ui/src/components/search/SearchResultNavButtons.svelte ui/src/components/search/SearchResults.svelte+147 ui/src/components/search/SearchResultsNavButtons.svelte+54 ui/src/components/search/SearchSettings.svelte+25 ui/src/components/search/sigil/ClanSelect.svelte+44 ui/src/components/search/sigil/ClanSelectOption.svelte+17 ui/src/components/search/sigil/GeonSelector.svelte+30 ui/src/components/search/sigil/MiniFakeSigil.svelte+25 ui/src/components/search/sigil/SigilInput.svelte+104 ui/src/components/search/sigil/Symbol.svelte+79 ui/src/components/search/sigil/SymbolInput.svelte+105 ui/src/components/search/sigil/SymbolInputModeSelector.svelte+168 ui/src/components/search/sigil/SymbolInputModeSelectorButton.svelte+33 ui/src/components/search/sigil/SymbolInputNavButtons.svelte+30 ui/src/components/ship_view/AzimuthDetails.svelte+90 ui/src/components/ship_view/ShipChain.svelte+11 ui/src/components/ship_view/ShipChildrenTabs.svelte+136 ui/src/components/ship_view/ShipView.svelte+130 ui/src/lib/api.ts+100−2 ui/src/lib/apps.ts+177 ui/src/lib/colors.ts+17 ui/src/lib/graph.ts+422 ui/src/lib/id.ts+35−6 ui/src/lib/link.ts+15−2 ui/src/lib/pals.ts+91 ui/src/lib/ship.ts+114 ui/src/lib/sigil.ts+387 ui/src/lib/utils.ts+49−8 ui/src/main.ts+5−2 ui/src/routes/HelpPage.svelte+26 ui/src/routes/Home.svelte+191−7 ui/src/routes/ShipViewPage.svelte−44 ui/src/routes/SigilPage.svelte+61 ui/src/stores/docs.ts+44 ui/src/stores/keys.ts+68 ui/src/stores/pageName.ts+12 ui/src/stores/searchStores.ts+66 ui/src/stores/store.ts+59−48 ui/src/styles/docs.scss+20−4 ui/src/styles/styles.scss+4−2 ui/src/styles/tailwind-output.css+1236−87 ui/src/types/sigil.ts+148 ui/src/types/store.ts+60−3 ui/svelte.config.js+2−2 ui/tailwind.config.cjs+23−1 ui/tsconfig.json+9 ui/vite.config.ts+22−2
.gitignore+1
@@ -1,3 +1,4 @@
11# OS X
22.DS_Store
33extras
4+globs
.vscode/settings.json+6
@@ -48,5 +48,11 @@
4848 }
4949 ]
5050 }
51+ ],
52+ "grammarly.selectors": [
53+ {
54+ "language": "markdown",
55+ "scheme": "file"
56+ }
5157 ]
5258}
.vscode/tasks.jsonnew file+13
@@ -0,0 +1,13 @@
1+{
2+ "version": "2.0.0",
3+ "tasks": [
4+ {
5+ "type": "npm",
6+ "script": "install:desk",
7+ "path": "ui",
8+ "problemMatcher": [],
9+ "label": "npm: install:desk - ui",
10+ "detail": "dotenv -c local npm run _install:desk"
11+ }
12+ ]
13+}
README.md+47−21
@@ -21,30 +21,56 @@ Astrolabe is built primarily using [Svelte], [Typescript], and [Tailwind CSS]. [
2121
2222To get started using Astrolabe first you need to run `npm install` inside the `ui` directory.
2323
24−To develop you'll need a running ship to point to. To do so you first need to add a `.env.local` file to the `ui` directory. This file will not be committed. Adding `VITE_SHIP_URL={URL}` where **{URL}** is the URL of the ship you would like to point to, will allow you to run `npm run dev`. This will proxy all requests to the ship except for those powering the interface, allowing you to see live data.
24+To develop you'll need a running ship to point to. If it's running somewhere other than `http://localhost:8081`, make a copy of `.env` in the `ui` directory and name it `.env.local`. This file will not be committed. Change `VITE_SHIP_URL` to the URL of the ship you would like to point to.
2525
26−Regardless of what you run to develop, Vite will hot-reload code changes as you work so you don't have to constantly refresh.
27−
28−### Deploying
29−
30−To deploy, run `npm run build` in the `ui` directory which will bundle all the code and assets into the `dist/` folder. This can then be made into a glob by doing the following:
26+Once your URL is correctly configured, you can run `npm run dev`. This will proxy all requests to the ship except for those powering the interface, allowing you to see live data.
3127
32−1. Create or launch an urbit using the -F flag
33−2. On that urbit, if you don't already have a desk to run from, run `|merge %work our %base` to create a new desk and mount it with `|mount %work`.
34−3. Now the `%work` desk is accessible through the host OS's filesystem as a directory of that urbit's pier ie `~/zod/work`.
35−4. From the `ui` directory you can run `rsync -avL --delete dist/ ~/zod/work/astrolabe` where `~/zod` is your fake urbit's pier.
36−5. Once completed you can then run `|commit %work` on your urbit and you should see your files logged back out from the dojo.
37−6. Now run `=dir /=garden` to switch to the garden desk directory
38−7. You can now run `-make-glob %work /astrolabe` which will take the folder where you just added files and create a glob which can be thought of as a sort of bundle. It will be output to `~/zod/.urb/put`.
39−8. If you navigate to `~/zod/.urb/put` you should see a file that looks like this `glob-0v5.fdf99.nph65.qecq3.ncpjn.q13mb.glob`. The characters between `glob-` and `.glob` are a hash of the glob's contents.
40−9. Now that we have the glob it can be uploaded to any publicly available HTTP endpoint that can serve files. This allows the glob to distributed over HTTP.
41−10. Once you've uploaded the glob, you should then update the corresponding entry in the docket file at `desk/desk.docket-0`. Both the full URL and the hash should be updated to match the glob we just created, on the line that looks like this:
42−
43−```hoon
44− glob-http+['https://bootstrap.urbit.org/glob-0v5.fdf99.nph65.qecq3.ncpjn.q13mb.glob' 0v5.fdf99.nph65.qecq3.ncpjn.q13mb]
45−```
28+Regardless of what you run to develop, Vite will hot-reload code changes as you work so you don't have to constantly refresh.
4629
47−11. This can now be safely committed and deployed.
30+# Deploying
31+
32+1. Spin up a comet or distribution ship.
33+2. Mount an `%astrolabe` desk. In Dojo:
34+ 1. `|merge %astrolabe our %base` to create a new desk.
35+ 2. `|mount %astrolabe` to mount it.
36+ 3. Set `ASTROLABE_DESK` in `.env.local` if the path to your desk is different.
37+3. Create and upload `glob-http`, if applicable (see below)
38+4. Bump the `version` in `desk.docket-0`.
39+3. Install the desk
40+ 1. From the `ui` folder: `npm run install:desk`
41+ 2. (first time only, on dev ship): `|install our %astrolabe`
42+ 2. From the distribution ship's dojo: `:treaty|unpublish %astrolabe`
43+ 2. From middleman or distribution ship's dojo: `|commit %astrolabe`
44+ 3. (if using a comet as a middleman) `|public %astrolabe`
45+ 4. (if using a comet as a middleman) from the actual distribution ship: `|install ~comet-name %astrolabe` or `|resume %astrolabe`
46+ 5. (if using a comet as a middleman) from the actual distribution ship: `|pause %astrolabe`
47+4. Build UI and upload `glob-ames`
48+5. Publish the desk from dojo: `:treaty|publish %astrolabe`
49+
50+## Deploying with `glob-ames` glob
51+Initial Setup:
52+1. Put the line `glob-ames+[~dister-midlev-mindyr 0v0]` in `desk.docket-0` if it's not there, where `~dister-midlevi-mindyr` is the `@p` of the distribution ship.
53+
54+Every Time:
55+4. Build the UI with `npm run build` in the `ui` directory which will bundle all the code and assets into the `dist/` folder.
56+5. Upload the `dist/` folder as a glob to your distribution ship. Example url: https://distribution.urbit-ship.com/docket/upload
57+
58+## Deploying with `glob-http` glob
59+Initial Setup:
60+1. Spin up a globber ship (comet or fakezod) (or just reuse your dev ship for this).
61+2. Mount an `%globber` desk. In Dojo:
62+ 1. `|merge %globber our %base` to create a new desk.
63+ 2. `|mount %globber` to mount it.
64+ 3. Set `GLOBBER_DESK` in `.env.local` if the path to your globber desk is different.
65+
66+Every Time:
67+3. From the `ui` directory, run `npm run release` to build the ui, make the glob, and copy it to the `globs` folder. The command will also print out the glob hash/id.
68+4. Copy the string printed by the last step, and paste it into `desk.docket-0`.
69+5. Upload the glob in `/globs/` to any publicly available HTTP endpoint that can serve files. This allows the glob to be distributed over HTTP.
70+6. Once you've uploaded the glob, paste the url into `desk/desk.docket-0`. Both the full URL and the hash should be updated to match the glob we just created, on the line that looks like this:
71+ ```hoon
72+ glob-http+['https://bootstrap.urbit.org/glob-0v5.fdf99.nph65.qecq3.ncpjn.q13mb.glob' 0v5.fdf99.nph65.qecq3.ncpjn.q13mb]
73+ ```
4874
4975[svelte]: https://svelte.dev/
5076[typescript]: https://www.typescriptlang.org/
base-desk/lib/agentio.hoon+4−6
@@ -66,7 +66,7 @@
6666 ::
6767 ++ rest
6868 |= p=@da
69− (arvo %b %wait p)
69+ (arvo %b %rest p)
7070 ::
7171 ++ warp
7272 |= [wer=ship =riff:clay]
@@ -85,16 +85,14 @@
8585 ?:(?=(%sing genre) [genre mood] [genre mood])
8686 (warp-our q.byk.bowl `rave)
8787 ::
88+ ++ tire
89+ (arvo %c %tire `~)
90+ ::
8891 ++ connect
8992 |= [=binding:eyre app=term]
9093 (arvo %e %connect binding app)
9194 --
9295::
93−++ fact-curry
94− |* [=mark =mold]
95− |= [paths=(list path) fac=mold]
96− (fact mark^!>(fac) paths)
97−::
9896++ fact-kick
9997 |= [=path =cage]
10098 ^- (list card)
base-desk/lib/azimuth.hoon+9−9
@@ -114,29 +114,29 @@
114114 ::
115115 :: Testnet contract addresses
116116 ::
117− ++ ropsten-contracts
117+ ++ goerli-contracts
118118 |%
119119 ++ azimuth
120− 0x308a.b6a6.024c.f198.b57e.008d.0ac9.ad02.1988.6579
120+ 0xbb61.fa68.3e4b.9104.18e2.7b00.a143.8a93.6234.df52
121121 ::
122122 ++ ecliptic
123− 0x8b9f.86a2.8921.d9c7.05b3.113a.755f.b979.e1bd.1bce
123+ 0xe129.0a32.9014.5e63.e6a8.ec1e.f661.6906.856d.0c8f
124124 ::
125125 ++ linear-star-release
126− 0x1f8e.dd03.1ee4.1474.0aed.b39b.84fb.8f2f.66ca.422f
126+ 0x0
127127 ::
128128 ++ conditional-star-release
129129 0x0
130130 ::
131131 ++ delegated-sending
132− 0x3e8c.a510.354b.c2fd.bbd6.1502.52d9.3105.c9c2.7bbe
132+ 0x0
133133 ::
134134 ++ naive
135− 0xe7cf.4b83.06d3.11ba.ca15.585f.e3f0.7cd0.441c.21d1
135+ 0x56e3.7137.cdaf.c026.a732.e8e8.40cd.621e.d50b.d210
136136 ::
137− ++ launch 4.601.630
138− ++ public launch
139− ++ chain-id 3
137+ ++ launch 7.834.742
138+ ++ public 7.834.800
139+ ++ chain-id 5
140140 --
141141 ::
142142 :: Local contract addresses
base-desk/lib/azimuthio.hoon+3−3
@@ -43,8 +43,8 @@
4343 url=url
4444 header-list=['Content-Type'^'application/json' ~]
4545 ^= body
46− %- some %- as-octt:mimes:html
47− %- en-json:html
46+ %- some %- as-octs:mimes:html
47+ %- en:json:html
4848 (request-to-json:rpc:ethereum id req)
4949 ==
5050 ;< ~ bind:m (send-request:strandio request)
@@ -62,7 +62,7 @@
6262 ?~ full-file.client-response
6363 (pure:m ~)
6464 =/ body=@t q.data.u.full-file.client-response
65− =/ jon=(unit json) (de-json:html body)
65+ =/ jon=(unit json) (de:json:html body)
6666 ?~ jon
6767 (pure:m ~)
6868 =, dejs-soft:format
base-desk/lib/bip/b173.hoon+1−1
@@ -11,7 +11,7 @@
1111|%
1212++ prefixes
1313 ^- (map network tape)
14− (my [[%main "bc"] [%testnet "tb"] ~])
14+ (my [[%main "bc"] [%testnet "tb"] [%regtest "bcrt"] ~])
1515++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
1616+$ raw-decoded [hrp=tape data=(list @) checksum=(list @)]
1717:: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js
base-desk/lib/bip/b174.hoon+2
@@ -56,6 +56,8 @@
5656 1^0x0
5757 %testnet
5858 1^0x1
59+ %regtest
60+ 1^0x1
5961 ==
6062 :- (cat:byt ~[1^typ pubkey.h])
6163 %- cat:byt
base-desk/lib/bitcoin-utils.hoon+2−1
@@ -143,6 +143,7 @@
143143 |= a=@
144144 ^- hexb
145145 =/ l=@ (met 3 a)
146+ ?: =(l 0) 1^a
146147 ?: =(l 1) 1^a
147148 ?: =(l 2) (cat:byt ~[1^0xfd (flip:byt 2^a)])
148149 ?: (lte l 4) (cat:byt ~[1^0xfe (flip:byt 4^a)])
@@ -162,7 +163,7 @@
162163 %0xfe 2
163164 %0xff 3
164165 ==
165− :_ (drop:byt (add 1 len) h)
166+ :_ (drop:byt (add 1 (bex len)) h)
166167 %- flip:byt
167168 (take:byt (bex len) (drop:byt 1 h))
168169 :: +dea: atom instead of hexb for parsed CompactSize
base-desk/lib/dbug.hoon+9−3
@@ -4,7 +4,8 @@
44::
55|%
66+$ poke
7− $% [%bowl ~]
7+ $% [%skip depth=@ud =poke]
8+ [%bowl ~]
89 [%state grab=cord]
910 [%incoming =about]
1011 [%outgoing =about]
@@ -32,8 +33,13 @@
3233 ?. ?=(%dbug mark)
3334 =^ cards agent (on-poke:ag mark vase)
3435 [cards this]
35− =/ dbug
36− !<(poke vase)
36+ =/ dbug !<(poke vase)
37+ =? dbug ?=([%skip %0 *] dbug) poke.dbug
38+ ?: ?=(%skip -.dbug)
39+ =^ cards agent
40+ %+ on-poke:ag %dbug
41+ !>(`poke`dbug(depth (dec depth.dbug)))
42+ [cards this]
3743 =; =tang
3844 ((%*(. slog pri 1) tang) [~ this])
3945 ?- -.dbug
base-desk/lib/dill.hoonnew file+94
@@ -0,0 +1,94 @@
1+:: dill: utilities for dill's data structures
2+::
3+=, dill
4+|%
5+++ enjs
6+ |%
7+ ++ blit
8+ |= =blit:dill
9+ ^- json
10+ =, enjs:format
11+ %+ frond -.blit
12+ ?- -.blit
13+ %bel b+&
14+ %clr b+&
15+ %hop ?@ p.blit (numb p.blit)
16+ (pairs 'x'^(numb x.p.blit) 'y'^(numb y.p.blit) ~)
17+ %put a+(turn p.blit |=(c=@c s+(tuft c)))
18+ %nel b+&
19+ %url s+p.blit
20+ %wyp b+&
21+ %mor a+(turn p.blit ^blit)
22+ ::
23+ %sag
24+ %- pairs
25+ :~ 'path'^(path p.blit)
26+ 'file'^s+(en:base64:mimes:html (as-octs:mimes:html (jam q.blit)))
27+ ==
28+ ::
29+ %sav
30+ %- pairs
31+ :~ 'path'^(path p.blit)
32+ 'file'^s+(en:base64:mimes:html (as-octs:mimes:html q.blit))
33+ ==
34+ ::
35+ %klr
36+ :- %a
37+ %+ turn p.blit
38+ |= [=stye text=(list @c)]
39+ %- pairs
40+ :~ 'text'^a+(turn text |=(c=@c s+(tuft c)))
41+ ::
42+ :- 'stye'
43+ %- pairs
44+ |^ :~ 'back'^(color p.q.stye)
45+ 'fore'^(color q.q.stye)
46+ 'deco'^a+(turn ~(tap in p.stye) |=(d=deco ?~(d ~ s+d)))
47+ ==
48+ ++ color
49+ |= =tint
50+ ?@ tint ?~(tint ~ s+tint)
51+ =, tint
52+ (pairs r+(numb r) g+(numb g) b+(numb b) ~)
53+ --
54+ ==
55+ ==
56+ --
57+::
58+++ dejs
59+ |%
60+ ++ belt
61+ |= jon=json
62+ ^- belt:dill
63+ ?: ?=([%s *] jon)
64+ (taft p.jon)
65+ =, dejs:format
66+ %. jon
67+ %- of
68+ |^ :* mod+(ot 'mod'^mod 'key'^bot ~)
69+ txt+(ar (cu taft so))
70+ bol
71+ ==
72+ ::
73+ ++ bol
74+ :~ aro+(su (perk %d %l %r %u ~))
75+ bac+ul
76+ del+ul
77+ hit+(ot 'x'^ni 'y'^ni ~)
78+ ret+ul
79+ ==
80+ ::
81+ ++ bot
82+ |= j=json
83+ ^- bolt:dill
84+ ?+ j !!
85+ [%s *] (taft p.j)
86+ [%o *] ((of bol) j)
87+ ==
88+ ::
89+ ++ mod
90+ |= j=json
91+ ((su (perk %ctl %met %hyp ~)) j)
92+ --
93+ --
94+--
base-desk/lib/ethereum.hoon+28−4
@@ -652,7 +652,7 @@
652652 :^ url %post
653653 %- ~(gas in *math)
654654 ~['Content-Type'^['application/json']~]
655− (some (as-octt (en-json:html jon)))
655+ (some (as-octs (en:json:html jon)))
656656 :: +light-json-request: like json-request, but for %l
657657 ::
658658 :: TODO: Exorcising +purl from our system is a much longer term effort;
@@ -665,7 +665,7 @@
665665 :* %'POST'
666666 (crip (en-purl:html url))
667667 ~[['content-type' 'application/json']]
668− (some (as-octt (en-json:html jon)))
668+ (some (as-octs (en:json:html jon)))
669669 ==
670670 ::
671671 ++ batch-read-request
@@ -733,7 +733,7 @@
733733 ::
734734 %eth-get-block-by-number
735735 :- 'eth_getBlockByNumber'
736− :~ (tape (num-to-hex bon.req))
736+ :~ (tape (num-to-hex-minimal bon.req))
737737 b+txs.req
738738 ==
739739 ::
@@ -942,12 +942,33 @@
942942 %- render-hex-bytes
943943 (as-octs:mimes:html n)
944944::
945+++ num-to-hex-minimal
946+ |= n=@
947+ ^- tape
948+ %- prefix-hex
949+ ((x-co:co 1) n)
950+::
945951++ address-to-hex
946952 |= a=address
947953 ^- tape
948954 %- prefix-hex
949955 (render-hex-bytes 20 `@`a)
950956::
957+++ address-to-checksum
958+ |= a=address
959+ ^- tape
960+ =/ hexed (render-hex-bytes 20 `@`a)
961+ =/ hash (keccak-256:keccak:crypto (as-octs:mimes:html (crip hexed)))
962+ =| ret=tape
963+ =/ pos 63
964+ |-
965+ ?~ hexed (prefix-hex (flop ret))
966+ =/ char i.hexed
967+ ?: (lth char 58) $(pos (dec pos), ret [char ret], hexed t.hexed)
968+ =/ nib (cut 2 [pos 1] hash)
969+ ?: (lth 7 nib) $(pos (dec pos), ret [(sub char 32) ret], hexed t.hexed)
970+ $(pos (dec pos), ret [char ret], hexed t.hexed)
971+::
951972++ transaction-to-hex
952973 |= h=@
953974 ^- tape
@@ -978,5 +999,8 @@
978999::
9791000++ hex-to-num
9801001 |= a=@t
981− (rash (rsh [3 2] a) hex)
1002+ ~| %non-hex-cord
1003+ ?> =((end [3 2] a) '0x')
1004+ =< ?<(=(0 p) q) %- need
1005+ (de:base16:mimes:html (rsh [3 2] a))
9821006--
base-desk/lib/ethio.hoon+3−3
@@ -76,8 +76,8 @@
7676 header-list=['Content-Type'^'application/json' ~]
7777 ::
7878 ^= body
79− %- some %- as-octt:mimes:html
80− %- en-json:html
79+ %- some %- as-octs:mimes:html
80+ %- en:json:html
8181 a+(turn reqs request-to-json:rpc:ethereum)
8282 ==
8383 ;< ~ bind:m
@@ -96,7 +96,7 @@
9696 ?~ full-file.client-response
9797 (pure:m ~)
9898 =/ body=@t q.data.u.full-file.client-response
99− =/ jon=(unit json) (de-json:html body)
99+ =/ jon=(unit json) (de:json:html body)
100100 ?~ jon
101101 (pure:m ~)
102102 =/ array=(unit (list response:rpc))
base-desk/lib/hark-store.hoon+22
@@ -171,6 +171,7 @@
171171++ dejs
172172 =, dejs:format
173173 |%
174+ ++ ship (su ;~(pfix sig fed:ag))
174175 :: TODO: fix +stab
175176 ::
176177 ++ pa
@@ -218,6 +219,26 @@
218219 :~ lid+lid
219220 bin+bin
220221 ==
222+ ++ content
223+ %- of
224+ :~ text+so
225+ ship+ship
226+ ==
227+ ::
228+ ++ body
229+ %- ot
230+ :~ title+(ar content)
231+ content+(ar content)
232+ time+di
233+ binned+pa
234+ link+pa
235+ ==
236+ ::
237+ ++ add-note
238+ %- ot
239+ :~ bin+bin
240+ body+body
241+ ==
221242 ::
222243 ++ action
223244 ^- $-(json ^action)
@@ -228,6 +249,7 @@
228249 read-count+place
229250 read-each+read-each
230251 read-note+bin
252+ add-note+add-note
231253 ==
232254 --
233255--
base-desk/lib/jose.hoon+11−3
@@ -33,7 +33,6 @@
3333 |^ |=([sor=$-(^ ?) val=json] (apex val sor ""))
3434 :: :: ++apex:en-json:html
3535 ++ apex
36− =, en-json:html
3736 |= [val=json sor=$-(^ ?) rez=tape]
3837 ^- tape
3938 ?~ val (weld "null" rez)
@@ -46,7 +45,7 @@
4645 |-
4746 ?~ t.p.val ^$(val i.p.val)
4847 ^$(val i.p.val, rez [',' $(p.val t.p.val)])
49− ::
48+ ::
5049 %b (weld ?:(p.val "true" "false") rez)
5150 %n (weld (trip p.val) rez)
5251 %s
@@ -60,7 +59,7 @@
6059 ?: ?=([@ ~] hed)
6160 [i.hed $(viz t.viz)]
6261 (weld hed $(viz t.viz))
63− ::
62+ ::
6463 %o
6564 :- '{'
6665 =. rez ['}' rez]
@@ -74,6 +73,15 @@
7473 =. rez [',' $(viz t.viz)]
7574 ^$(val [%s p.i.viz], rez [':' ^$(val q.i.viz)])
7675 ==
76+ ::
77+ ++ jesc
78+ =+ utf=|=(a=@ ['\\' 'u' ((x-co 4):co a)])
79+ |= a=@ ^- tape
80+ ?+ a ?:(&((gth a 0x1f) !=(a 0x7f)) [a ~] (utf a))
81+ %10 "\\n"
82+ %34 "\\\""
83+ %92 "\\\\"
84+ ==
7785 --
7886:: %/lib/jose
7987::
base-desk/lib/keygen.hoon+1−1
@@ -94,7 +94,7 @@
9494 |= seed=@
9595 ^- edkeys
9696 =+ =< [pub=pub:ex sec=sec:ex]
97− (pit:nu:crub:crypto 256 seed)
97+ (pit:nu:cric:crypto 256 seed %b ~)
9898 :- ^= auth
9999 :- (rsh 3 (end [3 33] pub))
100100 (rsh 3 (end [3 33] sec))
base-desk/lib/language-server/complete.hoon+4−3
@@ -3,7 +3,8 @@
33::
44=/ debug |
55|%
6−+* option [item]
6+++ option
7+ |$ [item]
78 [term=cord detail=item]
89::
910:: Like +rose except also produces line number
@@ -42,7 +43,7 @@
4243 %+ turn ~(tap by q.r.q.ty)
4344 |= [term =tome]
4445 %+ turn
45− ~(tap by q.tome)
46+ ~(tap by tome)
4647 |= [name=term =hoon]
4748 ^- (pair term type)
4849 ~| term=term
@@ -226,7 +227,7 @@
226227 =* outer-loop $
227228 ?~ tomes
228229 ~
229− =/ arms ~(tap by q.q.i.tomes)
230+ =/ arms ~(tap by q.i.tomes)
230231 |- ^- (unit [term type])
231232 =* inner-loop $
232233 ?~ arms
base-desk/lib/language-server/easy-print.hoon+3−3
@@ -421,11 +421,11 @@
421421 ?:(?=([%plot *] q.yon) [q.hin p.q.yon] [q.hin q.yon ~])
422422 ::
423423 [%core *]
424− ?: ?=([[%$ * [[%$ @ *] ~ ~]] ~ ~] q.r.q.sut)
424+ ?: ?=([[%$ [[%$ @ *] ~ ~]] ~ ~] q.r.q.sut)
425425 =/ dad $(sut p.sut)
426426 :- p.dad
427427 ~! q.r.q.sut
428− [%gate q.n.q.q.n.q.r.q.sut sut(r.p.q %gold) q.dad]
428+ [%gate q.n.q.n.q.r.q.sut sut(r.p.q %gold) q.dad]
429429 =+ yad=$(sut p.sut)
430430 :- p.yad
431431 =+ ^= doy ^- [p=(list @ta) q=wine]
@@ -438,7 +438,7 @@
438438 %^ cat 3
439439 %~ rent co
440440 :+ %$ %ud
441− %- ~(rep by (~(run by q.r.q.sut) |=(tome ~(wyt by q.+<))))
441+ %- ~(rep by (~(run by q.r.q.sut) |=(tome ~(wyt by +<))))
442442 |=([[@ a=@u] b=@u] (add a b))
443443 %^ cat 3
444444 ?-(r.p.q.sut %gold '.', %iron '|', %lead '?', %zinc '&')
base-desk/lib/language-server/rune-snippet.hoon+2−2
@@ -509,8 +509,8 @@
509509 :- '!@'
510510 """
511511 $\{1:wing}
512− $\{2:if-exists}
513− $\{3:if-not-exists}
512+ $\{2:if-not-exists}
513+ $\{3:if-exists}
514514 """
515515 :- '!?'
516516 """
base-desk/lib/noun-diff.hoonnew file+213
@@ -0,0 +1,213 @@
1+=<
2+|%
3+++ diff
4+ |= [old=* new=*]
5+ ^- patch
6+ =/ del (extract-del (oracle old new) old)
7+ =/ ins (extract-ins (oracle old new) new)
8+ =/ allowed-holes (~(int in (find-del-holes del)) (find-ins-holes ins))
9+ =. del (filter-del-holes allowed-holes del)
10+ =/ ins (filter-ins-holes allowed-holes ins)
11+ =/ closed-patch (closure (gcp [del ins]))
12+ ?> =(& +.closed-patch)
13+ -.closed-patch
14+++ apply
15+ |= [patch=_id noun=*]
16+ ?- -.patch
17+ %diff
18+ =/ var-map (del del.patch noun)
19+ (ins ins.patch var-map)
20+ ::
21+ %cell
22+ ?> ?=(^ noun)
23+ [$(patch lhs.patch, noun -.noun) $(patch rhs.patch, noun +.noun)]
24+ ==
25+++ id
26+ ^- patch
27+ [%diff [%hole ~] [%hole ~]]
28++$ patch
29+ $% [%cell lhs=patch rhs=patch]
30+ [%diff ^diff]
31+ ==
32+--
33+::
34+|%
35++$ del-diff
36+ $% [%hole @]
37+ [%cell lhs=del-diff rhs=del-diff]
38+ [%ignore ~]
39+ ==
40++$ ins-diff
41+ $% [%hole @ original=*]
42+ [%cell lhs=ins-diff rhs=ins-diff]
43+ [%atom @]
44+ ==
45++$ final-ins-diff
46+ $% [%hole @]
47+ [%cell lhs=final-ins-diff rhs=final-ins-diff]
48+ [%atom @]
49+ ==
50++$ diff [del=del-diff ins=final-ins-diff]
51++$ patch
52+ $% [%cell lhs=patch rhs=patch]
53+ [%diff diff]
54+ ==
55+++ insify-noun
56+ |= noun=*
57+ ^- final-ins-diff
58+ ?- noun
59+ ^ [%cell $(noun -.noun) $(noun +.noun)]
60+ @ [%atom noun]
61+ ==
62+++ empty-set (silt `(list @)`~)
63+++ find-del-holes
64+ |= diff=del-diff
65+ ~+
66+ ^- (set @)
67+ ?- -.diff
68+ %hole (silt ~[+.diff])
69+ %cell (~(uni in $(diff lhs.diff)) $(diff rhs.diff))
70+ %ignore empty-set
71+ ==
72+++ find-final-ins-holes
73+ |= diff=final-ins-diff
74+ ~+
75+ ^- (set @)
76+ ?- -.diff
77+ %hole (silt ~[+.diff])
78+ %cell (~(uni in $(diff lhs.diff)) $(diff rhs.diff))
79+ %atom empty-set
80+ ==
81+++ find-ins-holes
82+ |= diff=ins-diff
83+ ~+
84+ ^- (set @)
85+ ?- -.diff
86+ %hole (silt ~[+<.diff])
87+ %cell (~(uni in $(diff lhs.diff)) $(diff rhs.diff))
88+ %atom empty-set
89+ ==
90+++ filter-del-holes
91+ |= [allowed-holes=(set @) diff=del-diff]
92+ ^- del-diff
93+ ?: ?=(%ignore -.diff) diff
94+ ?- -.diff
95+ %hole ?:((~(has in allowed-holes) +.diff) diff [%ignore ~])
96+ %cell [%cell $(diff +<.diff) $(diff +>.diff)]
97+ ==
98+++ filter-ins-holes
99+ |= [allowed-holes=(set @) diff=ins-diff]
100+ ^- final-ins-diff
101+ ?- -.diff
102+ %cell [%cell $(diff +<.diff) $(diff +>.diff)]
103+ %atom diff
104+ %hole
105+ ?: (~(has in allowed-holes) +<.diff) [%hole +<.diff]
106+ (insify-noun original:diff)
107+ ==
108+++ gcp
109+ |= diff=diff
110+ ^- patch
111+ ?- -.ins.diff
112+ %atom [%diff diff]
113+ %hole [%diff diff]
114+ %cell
115+ ?. ?=(%cell -.del.diff)
116+ [%diff diff]
117+ [%cell $(diff [+<.del.diff +<.ins.diff]) $(diff [+>.del.diff +>.ins.diff])]
118+ ==
119+++ closure
120+ |= =patch
121+ ^- [^patch ?]
122+ ?- -.patch
123+ %diff
124+ =/ del-holes (find-del-holes del:patch)
125+ =/ ins-holes (find-final-ins-holes ins:patch)
126+ =/ difference (~(dif in ins-holes) del-holes)
127+ [patch =(difference empty-set)]
128+ ::
129+ %cell
130+ =/ lhs $(patch lhs:patch)
131+ =/ rhs $(patch rhs:patch)
132+ ?: ?&(+.lhs +.rhs) [[%cell -.lhs -.rhs] &]
133+ $(patch (pull-diff [%cell -.lhs -.rhs]))
134+ ==
135+++ pull-diff
136+ |= =patch
137+ ^- [%diff del=del-diff ins=final-ins-diff]
138+ ?- -.patch
139+ %diff patch
140+ %cell
141+ =/ pulled-lhs $(patch lhs:patch)
142+ =/ pulled-rhs $(patch rhs:patch)
143+ :+ %diff
144+ [%cell del:pulled-lhs del:pulled-rhs]
145+ [%cell ins:pulled-lhs ins:pulled-rhs]
146+ ==
147+++ is-subtree
148+ |= [tree=* subtree=*]
149+ ~+
150+ ^- ?
151+ ?: =(tree subtree) &
152+ ?@ tree |
153+ ?| (is-subtree -.tree subtree)
154+ (is-subtree +.tree subtree)
155+ ==
156+++ oracle
157+ |= [a=* b=*]
158+ |= subtree=*
159+ ^- (unit @)
160+ ?: ?& (is-subtree a subtree)
161+ (is-subtree b subtree)
162+ ==
163+ `(mug subtree)
164+ ~
165+++ extract-del
166+ |= [oracle=$-(* (unit @)) subtree=*]
167+ ~+
168+ ^- del-diff
169+ =/ hash (oracle subtree)
170+ ?^ hash [%hole +.hash]
171+ ?@ subtree [%ignore ~]
172+ [%cell (extract-del oracle -.subtree) (extract-del oracle +.subtree)]
173+++ extract-ins
174+ |= [oracle=$-(* (unit @)) subtree=*]
175+ ~+
176+ ^- ins-diff
177+ =/ hash (oracle subtree)
178+ ?^ hash [%hole +.hash subtree]
179+ ?@ subtree [%atom subtree]
180+ [%cell (extract-ins oracle -.subtree) (extract-ins oracle +.subtree)]
181+++ ins
182+ |= [diff=final-ins-diff var-map=(map @ *)]
183+ ^- *
184+ ?- -.diff
185+ %atom +.diff
186+ %cell [$(diff +<.diff) $(diff +>.diff)]
187+ %hole (~(got by var-map) +.diff)
188+ ==
189+++ del
190+ |= [diff=del-diff noun=*]
191+ ^- (map @ *)
192+ |^ (go diff noun ((map @ *) ~))
193+ ++ go
194+ |= [diff=del-diff noun=* var-map=(map @ *)]
195+ ^- (map @ *)
196+ ?- -.diff
197+ %ignore
198+ var-map
199+ ::
200+ %hole
201+ =/ subtree (~(get by var-map) +.diff)
202+ ?~ subtree (~(put by var-map) +.diff noun)
203+ ?> =(+.subtree noun)
204+ var-map
205+ ::
206+ %cell
207+ ?> ?=(^ noun)
208+ =/ lhs-var-map $(diff +<.diff, noun -.noun)
209+ =/ rhs-var-map $(diff +>.diff, noun +.noun, var-map lhs-var-map)
210+ rhs-var-map
211+ ==
212+ --
213+--
base-desk/lib/ph/io.hoon+238−4
@@ -1,5 +1,5 @@
11/- *aquarium, spider
2−/+ libstrand=strand, *strandio, util=ph-util
2+/+ libstrand=strand, *strandio, util=ph-util, aqua-azimuth, vere
33=, strand=strand:libstrand
44|%
55++ send-events
@@ -88,7 +88,6 @@
8888 ^- form:m
8989 (pure:m ~)
9090::
91−::
9291++ init
9392 =/ m (strand ,~)
9493 ^- form:m
@@ -125,9 +124,11 @@
125124 1
126125 +(+.old-rut)
127126 ;< ~ bind:m (send-azimuth-action %breach who)
127+ ;< ~ bind:m ?~ old-rut (sleep ~s20) :: XX don't wait if possible
128+ (wait-for-sunk her who) :: wait only if previously talked
128129 |- ^- form:m
129130 =* loop $
130− ;< ~ bind:m (sleep ~s1)
131+ ;< ~ bind:m (sleep ~s10)
131132 ;< =bowl:spider bind:m get-bowl
132133 =/ aqua-pax
133134 :- %i
@@ -137,14 +138,58 @@
137138 (pure:m ~)
138139 loop
139140::
141+++ init-moon ::NOTE real moon always have the same keys
142+ |= [moon=ship fake=?]
143+ ?> ?=(%earl (clan:title moon))
144+ ?: fake (init-ship moon &)
145+ =/ m (strand ,~)
146+ ;< ~ bind:m
147+ %+ dojo (^sein:title moon)
148+ =/ =pass pub:ex:(get-keys:aqua-azimuth moon 1)
149+ "|moon {(scow %p moon)}, =public-key {(scow %uw pass)}"
150+ (init-ship moon |)
151+::
140152++ init-ship
153+ =| core=?(%mesa %ames) :: XX make %mesa the default core
141154 |= [=ship fake=?]
142155 =/ m (strand ,~)
143156 ^- form:m
144157 ~& > "starting {<ship>}"
145− ;< ~ bind:m (send-events (init:util ship fake))
158+ ;< ~ bind:m (send-events (init:util ship fake ~ core))
146159 (check-ship-booted ship)
147160::
161+++ init-comet
162+ =| core=?(%mesa %ames) :: XX make %mesa the default core
163+ |= comet=ship
164+ =/ m (strand ,~)
165+ ^- form:m
166+ :: hardcoded for:
167+ :: ~londeg-tirlys-somlyd-poltus--pintyn-tarbyl-bicnux-marbud
168+ ::
169+ =/ =feed:jael
170+ :* [%2 ~]
171+ who=comet
172+ ryf=0
173+ :_ ~
174+ :- lyf=1
175+ key=0wfm.lBEWM.08gfy.AxYjy.8-tBQ.uq-aa.LZt9c.CVQqd.XBJIs.
176+ CoG90.BNNGV.1ZmVi.ZbAhY.LuhwC.idNnU.lCVkt.Z4qug.7iY92
177+ ==
178+ ::
179+ ?> ?=(^ (veri:dawn:vere comet feed *point:azimuth-types ~))
180+ ~& > "mining comet under {<(^sein:title comet)>}"
181+ ;< ~ bind:m (send-events (init:util comet fake=%.n `feed core))
182+ (check-ship-booted comet)
183+::
184+:: Load network core protocol
185+::
186+++ load
187+ |= [who=ship ore=?(%mesa %ames)]
188+ =/ m (strand ,~)
189+ ^- form:m
190+ ;< ~ bind:m (send-events [%event who [/a/aqua/load %load ore]]~)
191+ (pure:m ~)
192+::
148193++ check-ship-booted
149194 |= =ship
150195 =/ m (strand ,~)
@@ -181,6 +226,129 @@
181226 (pure:m ~)
182227 loop
183228::
229+++ wait-for-flub
230+ |= [our=ship her=ship dap=term]
231+ =/ m (strand ,~)
232+ ^- form:m
233+ ;< =bowl:spider bind:m get-bowl
234+ |- ^- form:m
235+ =* loop $
236+ ;< [from=^ship =unix-effect] bind:m take-unix-effect
237+ ;< now=@da bind:m get-time
238+ ?. =(from our)
239+ :: our sends the $boon with the halted flow number, at this point
240+ :: gall has updated its state adding the app to gall's .halts map
241+ :: XX search deeper in the .unix-effect?
242+ ::
243+ loop
244+ =/ aqua-pax
245+ :- %i
246+ /(scot %p our)/gg/(scot %p our)//(scot %da now)/[%$]/noun
247+ =+ ;; flubs=(unit (jug ship term))
248+ (scry-aqua:util noun our.bowl now aqua-pax)
249+ ?~ flubs loop
250+ ?. (~(has ju u.flubs) her dap)
251+ loop
252+ (pure:m ~)
253+::
254+++ wait-for-spur
255+ |= [our=ship her=ship dap=term]
256+ =/ m (strand ,~)
257+ ^- form:m
258+ ;< =bowl:spider bind:m get-bowl
259+ |- ^- form:m
260+ =* loop $
261+ ;< [from=ship =unix-effect] bind:m take-unix-effect
262+ ;< now=@da bind:m get-time
263+ ?. =(from our)
264+ :: our ack to the %spur $boon is sent, at this point
265+ :: gall has updated its state adding the app to gall's .flubs map
266+ :: XX search deeper in the .unix-effect?
267+ ::
268+ loop
269+ =/ aqua-pax
270+ :- %i
271+ /(scot %p our)/gg/(scot %p our)//(scot %da now)/[%$]/noun
272+ =+ ;; flubs=(unit (jug ship term))
273+ (scry-aqua:util noun our.bowl now aqua-pax)
274+ ?~ flubs loop
275+ ?: (~(has ju u.flubs) her dap)
276+ loop
277+ (pure:m ~)
278+::
279+++ wait-for-has-halt
280+ |= [our=ship her=ship dap=term]
281+ =/ m (strand ,~)
282+ ^- form:m
283+ ;< =bowl:spider bind:m get-bowl
284+ |- ^- form:m
285+ =* loop $
286+ ;< [from=ship =unix-effect] bind:m take-unix-effect
287+ ;< now=@da bind:m get-time
288+ :: only %send or %push effects
289+ ::
290+ ?. ?=(?(%send %push) -.q.unix-effect)
291+ loop
292+ ~& >> from^unix-effect
293+ ?. =(from our)
294+ :: wait until our ack for the %flub $boon is sent, at this point
295+ :: gall has updated its state adding the app to gall's .flubs map
296+ :: XX search deeper in the .unix-effect?
297+ ::
298+ loop
299+ =/ aqua-pax
300+ :- %i
301+ /(scot %p our)/gh/(scot %p our)//(scot %da now)/[%$]/noun
302+ =+ ;; halts=(unit (jug app=term [ship =duct]))
303+ (scry-aqua:util noun our.bowl now aqua-pax)
304+ ?~ halts loop
305+ ?. (~(has by u.halts) dap) :: XX check .her as well
306+ loop
307+ (pure:m ~)
308+::
309+++ wait-for-del-halt
310+ |= [our=ship her=ship dap=term]
311+ =/ m (strand ,~)
312+ ^- form:m
313+ ;< =bowl:spider bind:m get-bowl
314+ |- ^- form:m
315+ =* loop $
316+ ;< [from=ship =unix-effect] bind:m take-unix-effect
317+ ;< now=@da bind:m get-time
318+ ?. =(from our)
319+ :: when the %spur $boon has been sent, gall has updated its state deleting
320+ :: the app from gall's .flubs map
321+ :: XX search deeper in the .unix-effect?
322+ ::
323+ loop
324+ =/ aqua-pax
325+ :- %i
326+ /(scot %p our)/gh/(scot %p our)//(scot %da now)/[%$]/noun
327+ =+ ;; halts=(unit (jug app=term [ship =duct]))
328+ (scry-aqua:util noun our.bowl now aqua-pax)
329+ ?~ halts loop
330+ ?: (~(has by u.halts) dap) :: XX check .her as well
331+ loop
332+ (pure:m ~)
333+::
334+++ wait-for-pac
335+ |= [our=ship to=ship]
336+ =/ m (strand ,~)
337+ ^- form:m
338+ ~& > "waiting for ack: {<[from=our to=to]>}"
339+ |- ^- form:m
340+ =* loop $
341+ ;< [from=ship =unix-effect] bind:m take-unix-effect
342+ ?. =(our from)
343+ loop
344+ :: only %send or %push effects
345+ ::
346+ ?. ?=(?(%send %push) -.q.unix-effect)
347+ loop
348+ :: XX check that this is an %ack?
349+ :: XX check that this is for .to?
350+ ::
351+ (pure:m ~)
184352:: Send "|hi" from one ship to another
185353::
186354++ send-hi
@@ -192,6 +360,64 @@
192360::
193361:: Send "|hi" and wait for "not responding" message
194362::
363+++ wait-for-sunk
364+ |= [from=@p to=@p]
365+ =/ m (strand ,~)
366+ (wait-for-output from "{(scow %p to)} has sunk")
367+::
368+++ wait-for-fact
369+ |= [=ship =mark =wire gate=$-([mark noun] ?)]
370+ =/ m (strand ,noun)
371+ ^- form:m
372+ ~& > "waiting for fact: {<mark>}"
373+ |- ^- form:m
374+ =* loop $
375+ ;< [her=^ship =unix-effect] bind:m take-unix-effect
376+ ?. =(her ship)
377+ loop
378+ ?. ?& =(wire p.unix-effect)
379+ ?=([%unto %raw-fact *] q.unix-effect)
380+ =(mark mark.unto.q.unix-effect)
381+ (gate mark noun.unto.q.unix-effect)
382+ ==
383+ loop
384+ (pure:m noun.unto.q.unix-effect)
385+::
386+++ wait-for-cork
387+ |= [our=ship her=ship flow=(each bone:ames side:ames)]
388+ =/ m (strand ,~)
389+ ^- form:m
390+ ;< =bowl:spider bind:m get-bowl
391+ |- ^- form:m
392+ =* loop $
393+ ;< [from=ship =unix-effect] bind:m take-unix-effect
394+ ;< now=@da bind:m get-time
395+ :: only %send or %push effects
396+ ::
397+ ?. ?=(?(%send %push) -.q.unix-effect)
398+ loop
399+ :: XX check that this is an %ack?
400+ ::
401+ ?. =(from our)
402+ :: wait until the ack for the %cork $plea is sent, at this point
403+ :: the publisher has already corked the flow
404+ ::
405+ loop
406+ =/ aqua-pax
407+ %+ weld /i/(scot %p our)/ax/(scot %p our)//(scot %da now)
408+ ?: ?=(%& -.flow)
409+ /corked/(scot %p her)/(scot %ud +.flow)/noun
410+ =/ [=bone:ames =dire:ames] +.flow
411+ /corked/(scot %p her)/[dire]/(scot %ud bone)/noun
412+ =+ ;; corked=(unit ?) (scry-aqua:util noun our.bowl now aqua-pax)
413+ ?~ corked loop
414+ ?. u.corked :: XX check .her as well
415+ loop
416+ ~& >> flow-is-corked/flow
417+ (pure:m ~)
418+::
419+:: Send "|hi" and wait for "not responding" message
420+::
195421++ send-hi-not-responding
196422 |= [from=@p to=@p]
197423 ~& > 'sending hi not responding'
@@ -244,6 +470,14 @@
244470 ;< ~ bind:m (send-events (insert-files:util her desk [pax warped] ~))
245471 (pure:m warped)
246472::
473+++ copy-file
474+ =/ m (strand ,~)
475+ |= [her=ship pax=path file=@t]
476+ ^- form:m
477+ ;< ~ bind:m
478+ (send-events (insert-files:util her %base [pax file] ~))
479+ (sleep ~s1)
480+::
247481:: Check /sur/aquarium/hoon on the given has the given contents.
248482::
249483++ check-file-touched
base-desk/lib/ph/util.hoon+25−12
@@ -16,9 +16,11 @@
1616:: Start a ship (low-level; prefer +raw-ship)
1717::
1818++ init
19− |= [who=ship fake=?]
19+ |= [who=ship ake=? eed=(unit feed:jael) ore=?(%mesa %ames)]
2020 ^- (list aqua-event)
21− [%init-ship who fake]~
21+ :~ [%init-ship who ake eed]
22+ [%event who [/a/aqua/load %load ore]]
23+ ==
2224::
2325:: Send dojo command
2426::
@@ -28,8 +30,8 @@
2830 %+ send-events-to who
2931 ^- (list unix-event)
3032 :~
31− [/d/term/1 %belt %ctl `@c`%e]
32− [/d/term/1 %belt %ctl `@c`%u]
33+ [/d/term/1 %belt %mod %ctl `@c`%e]
34+ [/d/term/1 %belt %mod %ctl `@c`%u]
3335 [/d/term/1 %belt %txt ((list @c) what)]
3436 [/d/term/1 %belt %ret ~]
3537 ==
@@ -40,7 +42,7 @@
4042 |= [who=ship what=term]
4143 ^- (list ph-event)
4244 %+ send-events-to who
43− :~ [/d/term/1 %belt %ctl (,@c what)]
45+ :~ [/d/term/1 %belt %mod %ctl (,@c what)]
4446 ==
4547::
4648:: Inject a file into a ship
@@ -59,18 +61,29 @@
5961::
6062:: Checks whether the given event is a dojo output blit containing the
6163:: given tape
62−::
64+::TODO should be rename -dill-output
6365++ is-dojo-output
6466 |= [who=ship her=ship uf=unix-effect what=tape]
67+ |^
6568 ?& =(who her)
6669 ?=(%blit -.q.uf)
67− ::
68− %+ lien p.q.uf
69− |= =blit:dill
70− ?. ?=(%lin -.blit)
71− |
72− !=(~ (find what p.blit))
70+ (lien p.q.uf handle-blit)
7371 ==
72+ ::
73+ ++ handle-blit
74+ |= =blit:dill
75+ ^- ?
76+ ?: ?=(%mor -.blit)
77+ (lien p.blit handle-blit)
78+ ?+ -.blit |
79+ %put !=(~ (find what p.blit))
80+ ::
81+ %klr
82+ %+ lien p.blit
83+ |= [* q=(list @c)]
84+ !=(~ (find what q))
85+ ==
86+ --
7487::
7588:: Test is successful if +is-dojo-output
7689::
base-desk/lib/pill.hoon+500−18
@@ -2,6 +2,7 @@
22::
33/- dice
44^?
5+=<
56|%
67::
78+$ pill
@@ -11,6 +12,14 @@
1112 boot-ova=(list)
1213 kernel-ova=(list unix-event)
1314 userspace-ova=(list unix-event)
15+ ==
16+ $: %cash
17+ $: nam=term
18+ boot-ova=(list)
19+ kernel-ova=(list unix-event)
20+ userspace-ova=(list unix-event)
21+ ==
22+ cache=(list)
1423 == ==
1524::
1625+$ unix-event
@@ -32,25 +41,23 @@
3241 [/sys/hoon hoon/hoon]
3342 [/sys/arvo hoon/arvo]
3443 ==
44+:: +dirs: filter for userspace directories to include
45+::
46+++ dirs
47+ |= [bas=path exc=(list spur)]
48+ ^- (list spur)
49+ ?~ exc ~(tap in dir:.^(arch %cy bas))
50+ %+ skim
51+ ~(tap in dir:.^(arch %cy bas))
52+ |=(=spur =(~ (find ~[spur] exc)))
3553:: +file-ovum: userspace filesystem load
3654::
3755:: bas: full path to / directory
3856::
3957++ file-ovum
40− =/ directories=(list path)
41− :~ /app :: %gall applications
42− /gen :: :dojo generators
43− /lib :: libraries
44− /mar :: mark definitions
45− /sur :: structures
46− /sys :: system files
47− /ted :: :spider strands
48− /web :: %eyre web content
49− /desk :: desk manifest
50− ==
51− |= [des=desk bas=path]
58+ |= [des=desk bas=path exc=(list spur)]
5259 ^- unix-event
53− %. directories
60+ %. (dirs bas exc)
5461 |= :: sal: all spurs to load from
5562 ::
5663 sal=(list spur)
@@ -61,9 +68,13 @@
6168 =; hav ~& user-files+(lent hav)
6269 =/ =yuki:clay
6370 :- *(list tako:clay)
64− %- ~(gas by *(map path (each page:clay lobe:clay)))
65− (turn hav |=([=path =page:clay] [path &+page]))
71+ %- ~(gas by *(map path (each page lobe:clay)))
72+ (turn hav |=([=path =page] [path &+page]))
6673 [/c/sync [%park des &+yuki *rang:clay]]
74+ (file-pages bas sal)
75+::
76+++ file-pages
77+ |= [bas=path sal=(list spur)]
6778 =| hav=(list [path page:clay])
6879 |- ^+ hav
6980 ?~ sal ~
@@ -95,13 +106,43 @@
95106::
96107:: +file-ovum2: electric boogaloo
97108::
98−++ file-ovum2 |=(p=path `unix-event`[//arvo what/(user-files p)])
109+++ file-ovum2 |=(z=[path (list spur)] `unix-event`[//arvo what/(user-files z)])
110+::
111+++ get-wynn
112+ |= [sys=path new-wynn=?]
113+ ^- wynn
114+ ?. new-wynn
115+ :~ zuse+zuse
116+ lull+lull
117+ arvo+arvo
118+ hoon+hoon-version
119+ ==
120+ ~> %bout.[0 %get-wynn]
121+ =+ .^(zus=vase %ca (welp sys /zuse/hoon))
122+ =+ .^(lul=vase %ca (welp sys /lull/hoon))
123+ =+ .^(arv=vase %ca (welp sys /arvo/hoon))
124+ =+ .^(hun=vase %ca (welp sys /hoon/hoon))
125+ :~ [%zuse ;;(@ud q:(slap zus limb+%zuse))]
126+ [%lull ;;(@ud q:(slap lul limb+%lull))]
127+ [%arvo ;;(@ud q:(slap arv limb+%arvo))]
128+ [%hoon ;;(@ud q:(slap hun limb+%hoon-version))]
129+ ==
130+::
131+++ prep-ovum
132+ |= dez=(list path)
133+ ^- unix-event
134+ =- ~& clay-blobs+~(wyt by -)
135+ [/c/inflate [%prep -]]
136+ %+ roll dez
137+ |= [bas=path out=(map lobe:clay page:clay)]
138+ %- ~(uni by out)
139+ .^(_out %cs (snoc bas %bloc))
99140::
100141:: +user-files: all userspace hoon files
101142::
102143++ user-files
103− |= bas=path
104− %. directories:file-ovum
144+ |= [bas=path exc=(list spur)]
145+ %. (dirs bas exc)
105146 |= sal=(list spur)
106147 ^- (list (pair path (cask)))
107148 ::
@@ -135,4 +176,445 @@
135176 |- ^+ hav
136177 ?~ all hav
137178 $(all t.all, hav ^$(tyl [p.i.all tyl]))
179+::
180+::TODO include %prep task in solid and brass?
181+++ solid
182+ :: sys: root path to boot system, `/~me/[desk]/now/sys`
183+ :: dez: secondary desks and their root paths
184+ :: exc: list of desk folders to exclude
185+ ::
186+ |= [sys=path dez=(list [desk path]) dub=? now=@da prime=? exc=(list spur)]
187+ ^- pill
188+ =/ bas=path (scag 3 sys)
189+ =/ compiler-path (weld sys /hoon)
190+ =/ arvo-path (weld sys /arvo)
191+ ~& %solid-start
192+ =/ compiler-src .^(@t %cx (weld compiler-path /hoon))
193+ =/ arvo-src .^(@t %cx (weld arvo-path /hoon))
194+ =/ arvo-formula
195+ ~& %solid-loaded
196+ =/ compiler-hoon (rain compiler-path compiler-src)
197+ ?. dub
198+ :: compile arvo against hoon, with our current compiler
199+ ::
200+ =/ whole-hoon=hoon
201+ [%tsgr compiler-hoon [%tsgr [%$ 7] (rain arvo-path arvo-src)]]
202+ ~& %solid-parsed
203+ =/ whole-formula q:(~(mint ut %noun) %noun whole-hoon)
204+ ~& %solid-arvo
205+ whole-formula
206+ :: compile arvo against hoon, with a freshly compiled hoon (via +ride)
207+ ::
208+ ~& %solid-parsed
209+ =/ compiler-formula q:(~(mint ut %noun) %noun compiler-hoon)
210+ ~& %solid-compiled
211+ =/ whole-src
212+ (rap 3 ['=> ' compiler-src '=> +7 ' arvo-src ~])
213+ ~& %solid-double-loaded
214+ =/ whole-formula
215+ =< +
216+ .* [%noun whole-src]
217+ [%8 compiler-formula [%9 2 %10 [6 %0 3] [%0 2]]]
218+ ~& %solid-double-compiled
219+ whole-formula
220+ ::
221+ ~& [%solid-kernel `@ux`(mug arvo-formula)]
222+ ::
223+ :: installed: Arvo gate (formal interface) with %zuse and vanes installed
224+ ::
225+ =/ installed
226+ =< q
227+ %^ spin
228+ ^- (list ovum)
229+ :- (boot-ovum:pill compiler-src arvo-src)
230+ %+ turn
231+ (snoc (turn dez tail) bas)
232+ |= =path
233+ (file-ovum2 [path exc])
234+ .*(0 arvo-formula)
235+ |= [ovo=ovum ken=*]
236+ [~ (slum ken [now ovo])]
237+ ::
238+ :: kernel-formula
239+ ::
240+ :: We evaluate :arvo-formula (for jet registration),
241+ :: then ignore the result and produce .installed
242+ ::
243+ =/ kernel-formula
244+ [%7 arvo-formula %1 installed]
245+ ::
246+ :: boot-two: startup formula
247+ ::
248+ =/ boot-two
249+ => *[kernel-formula=^ tale=*]
250+ != [.*(0 kernel-formula) tale]
251+ ::
252+ :: boot-ova
253+ ::
254+ =/ boot-ova=(list)
255+ [aeon:eden:part boot-two kernel-formula ~]
256+ ::
257+ :: a pill is a 3-tuple of event-lists: [boot kernel userspace]
258+ ::
259+ :: Our kernel event-list is ~, as we've already installed them.
260+ :: Our userspace event-list is a list containing a full %clay
261+ :: filesystem sync event.
262+ ::
263+ :+ %pill %solid
264+ :+ boot-ova ~
265+ =. dez (snoc dez [%base bas])
266+ ;: weld
267+ %+ turn dez
268+ |= [dek=desk bas=path]
269+ (file-ovum [dek bas exc])
270+ ::
271+ ?. prime ~
272+ [(prep-ovum (turn dez tail))]~
273+ ::
274+ %+ turn dez
275+ |= [dek=desk *]
276+ ^- unix-event
277+ [/c/essential/[dek] %esse dek %.y]
278+ ==
279+::
280+++ brass
281+ :: sys: root path to boot system, `/~me/[desk]/now/sys`
282+ :: dez: secondary desks and their root paths
283+ :: exc: list of desk folders to exclude
284+ ::
285+ |= [sys=path dez=(list [desk path]) cache=? prime=? new-wynn=? exc=(list spur)]
286+ ^- pill
287+ =/ bas=path (scag 3 sys)
288+ :: compiler-source: hoon source file producing compiler, `sys/hoon`
289+ ::
290+ =+ compiler-source=.^(@t %cx (welp sys /hoon/hoon))
291+ ::
292+ :: compiler-twig: compiler as hoon expression
293+ ::
294+ ~& %brass-parsing
295+ =+ compiler-twig=(rain /sys/hoon/hoon compiler-source)
296+ ~& %brass-parsed
297+ ::
298+ :: compiler-formula: compiler as nock formula
299+ ::
300+ ~& %brass-compiling
301+ =+ compiler-formula=q:(~(mint ut %noun) %noun compiler-twig)
302+ ~& %brass-compiled
303+ ::
304+ :: arvo-source: hoon source file producing arvo kernel, `sys/arvo`
305+ ::
306+ =+ arvo-source=.^(@t %cx (welp sys /arvo/hoon))
307+ ::
308+ :: boot-ova: startup events
309+ ::
310+ =/ boot-ova=(list)
311+ :~ aeon:eden:part
312+ boot:eden:part
313+ compiler-formula
314+ compiler-source
315+ arvo-source
316+ ==
317+ ::
318+ =/ kernel-ova=(list unix-event)
319+ :~ (boot-ovum compiler-source arvo-source)
320+ (file-ovum2 [bas exc])
321+ ==
322+ ::
323+ =/ userspace-ova
324+ =. dez (snoc dez [%base bas])
325+ ;: weld
326+ %+ turn dez
327+ |= [dek=desk bas=path]
328+ (file-ovum [dek bas exc])
329+ ::
330+ ?. prime ~
331+ [(prep-ovum (turn dez tail))]~
332+ ::
333+ %+ turn dez
334+ |= [dek=desk *]
335+ ^- unix-event
336+ [/c/essential/[dek] %esse dek %.y]
337+ ==
338+ ::
339+ =/ =wynn (get-wynn sys new-wynn)
340+ ::
341+ =/ cache=(list)
342+ ?. cache ~
343+ %~ tap by
344+ =< +
345+ %- mice
346+ :_ [%2 [%0 3] %0 2]
347+ ;: weld
348+ boot-ova
349+ ^- (list)
350+ :~ [*@da //arvo %wack *@uvJ]
351+ [*@da //arvo %whom *@p]
352+ [*@da //arvo %wyrd [~.nonce /] wynn]
353+ ==
354+ `(list)`(turn kernel-ova (lead *@da))
355+ `(list)`[*@da [/d/term/1 %boot & %fake *@p]]^~
356+ `(list)`(turn userspace-ova (lead *@da))
357+ `(list)`[*@da [/c/init-zest %zeal (turn dez |=([d=desk *] [d %live]))]]^~
358+ ==
359+ ::
360+ ~> %slog.[0 leaf+"brass: cache entries: {<(lent cache)>}"]
361+ ::
362+ :- %cash
363+ :_ cache
364+ [%brass boot-ova kernel-ova userspace-ova]
365+::
366+++ ivory
367+ |= sys=path
368+ ^- pill
369+ =/ lib (snoc (scag 3 sys) %lib)
370+ |^ =/ ver
371+ =/ sub *(trap vase)
372+ =. sub (build-sys sub %hoon)
373+ =. sub (build-sys sub %arvo)
374+ =. sub (build-sys sub %lull)
375+ =. sub (build-sys sub %zuse)
376+ =. sub (build-lib sub & %ethereum)
377+ =. sub (build-lib sub & %azimuth)
378+ (build-lib sub | %vere)
379+ =/ nok !.
380+ => *[ver=(trap vase) ~]
381+ != q:$:ver
382+ ivory/[nok ver ~]
383+ ::
384+ ++ build-sys
385+ |= [sub=(trap vase) nam=term] ^- (trap vase)
386+ ~> %slog.[0 leaf+"ivory: building /sys/{(trip nam)}"]
387+ (swat sub (rain /sys/[nam]/hoon .^(@t cx+(welp sys /[nam]/hoon))))
388+ ::
389+ ++ build-lib
390+ |= [sub=(trap vase) imp=? nam=term] ^- (trap vase)
391+ ~> %slog.[0 leaf+"ivory: building /lib/{(trip nam)}"]
392+ =/ hun=hoon
393+ %+ mist /lib/[nam]/hoon
394+ .^(@t cx+(welp lib /[nam]/hoon))
395+ ?. imp (swat sub hun)
396+ (swel sub [%ktts nam hun])
397+ :: +mist: +rain but skipping past ford runes
398+ ::
399+ ++ mist
400+ |= [bon=path txt=@]
401+ ^- hoon
402+ =+ vas=vast
403+ ~| bon
404+ %+ scan (trip txt)
405+ %- full
406+ =; fud
407+ (ifix [;~(plug gay fud) gay] tall:vas(wer bon))
408+ %- star
409+ ;~ pose vul
410+ %+ ifix [fas (just `@`10)]
411+ (star ;~(less (just `@`10) next))
412+ ==
413+ :: +swel: +swat but with +slop
414+ ::
415+ ++ swel
416+ |= [tap=(trap vase) gen=hoon]
417+ ^- (trap vase)
418+ =/ gun (~(mint ut p:$:tap) %noun gen)
419+ => [tap=tap gun=gun]
420+ |. ~+
421+ =/ pro q:$:tap
422+ [[%cell p.gun p:$:tap] [.*(pro q.gun) pro]]
423+ --
424+::
425+++ events
426+ |%
427+ +$ prop [%prop meta tier (list ovum)]
428+ +$ meta term
429+ +$ tier ?(%fore %hind) :: before or after userspace
430+ ::
431+ ++ install
432+ |= [as=desk =beak pri=?]
433+ ^- prop
434+ :^ %prop (rap 3 %install '-' as ~) %hind
435+ ::TODO will exclude non-:directories files, such as /changelog/txt
436+ =- (murn - same)
437+ ^- (list (unit ovum))
438+ :~ `(file-ovum as (en-beam beak /) ~)
439+ ::
440+ ?. pri ~
441+ `(prep-ovum (en-beam beak /) ~)
442+ ::
443+ `[/d/install/[as] [%seat as]]
444+ ==
445+ --
446+--
447+::
448+~% %non ..part ~
449+:: +mice: %memo hint caching version of mink
450+::
451+|%
452+++ mice !.
453+ ~/ %mice
454+ |= [subject=* formula=*]
455+ =| trace=(list [@ta *])
456+ =| memo=(map)
457+ =; [ton=tone mem=_memo]
458+ ?. ?=(%0 -.ton)
459+ [ton ~]
460+ [ton mem]
461+ |^ ^- [tone _memo]
462+ ?+ formula [[%2 trace] memo]
463+ [^ *]
464+ =^ head memo $(formula -.formula)
465+ ?. ?=(%0 -.head) [head memo]
466+ =^ tail memo $(formula +.formula)
467+ :_ memo
468+ ?. ?=(%0 -.tail) tail
469+ [%0 product.head product.tail]
470+ ::
471+ [%0 axis=@]
472+ :_ memo
473+ =/ part (frag axis.formula subject)
474+ ?~ part [%2 trace]
475+ [%0 u.part]
476+ ::
477+ [%1 constant=*]
478+ [[%0 constant.formula] memo]
479+ ::
480+ [%2 subject=* formula=*]
481+ =^ subject memo $(formula subject.formula)
482+ ?. ?=(%0 -.subject) [subject memo]
483+ =^ formula memo $(formula formula.formula)
484+ ?. ?=(%0 -.formula) [formula memo]
485+ %= $
486+ subject product.subject
487+ formula product.formula
488+ ==
489+ ::
490+ [%3 argument=*]
491+ =^ argument memo $(formula argument.formula)
492+ :_ memo
493+ ?. ?=(%0 -.argument) argument
494+ [%0 .?(product.argument)]
495+ ::
496+ [%4 argument=*]
497+ =^ argument memo $(formula argument.formula)
498+ :_ memo
499+ ?. ?=(%0 -.argument) argument
500+ ?^ product.argument [%2 trace]
501+ [%0 .+(product.argument)]
502+ ::
503+ [%5 a=* b=*]
504+ =^ a memo $(formula a.formula)
505+ ?. ?=(%0 -.a) [a memo]
506+ =^ b memo $(formula b.formula)
507+ :_ memo
508+ ?. ?=(%0 -.b) b
509+ [%0 =(product.a product.b)]
510+ ::
511+ [%6 test=* yes=* no=*]
512+ =^ result memo $(formula test.formula)
513+ ?. ?=(%0 -.result) [result memo]
514+ ?+ product.result [[%2 trace] memo]
515+ %& $(formula yes.formula)
516+ %| $(formula no.formula)
517+ ==
518+ ::
519+ [%7 subject=* next=*]
520+ =^ subject memo $(formula subject.formula)
521+ ?. ?=(%0 -.subject) [subject memo]
522+ %= $
523+ subject product.subject
524+ formula next.formula
525+ ==
526+ ::
527+ [%8 head=* next=*]
528+ =^ head memo $(formula head.formula)
529+ ?. ?=(%0 -.head) [head memo]
530+ %= $
531+ subject [product.head subject]
532+ formula next.formula
533+ ==
534+ ::
535+ [%9 axis=@ core=*]
536+ =^ core memo
537+ $(formula core.formula)
538+ ?. ?=(%0 -.core) [core memo]
539+ =/ arm (frag axis.formula product.core)
540+ ?~ arm [[%2 trace] memo]
541+ %= $
542+ subject product.core
543+ formula u.arm
544+ ==
545+ ::
546+ [%10 [axis=@ value=*] target=*]
547+ ?: =(0 axis.formula) [[%2 trace] memo]
548+ =^ target memo $(formula target.formula)
549+ ?. ?=(%0 -.target) [target memo]
550+ =^ value memo $(formula value.formula)
551+ :_ memo
552+ ?. ?=(%0 -.value) value
553+ =/ mutant=(unit *)
554+ (edit axis.formula product.target product.value)
555+ ?~ mutant [%2 trace]
556+ [%0 u.mutant]
557+ ::
558+ [%11 tag=@ next=*]
559+ =^ next memo $(formula next.formula)
560+ :_ memo
561+ ?. ?=(%0 -.next) next
562+ :- %0
563+ .* subject
564+ [11 tag.formula 1 product.next]
565+ ::
566+ [%11 [tag=@ clue=*] next=*]
567+ =^ clue memo $(formula clue.formula)
568+ ?. ?=(%0 -.clue) [clue memo]
569+ ?: ?=(%memo tag.formula)
570+ ?^ hit=(~(get by memo) subject next.formula)
571+ [[%0 u.hit] memo]
572+ =^ ton memo $(formula next.formula)
573+ ?. ?=(%0 -.ton)
574+ [ton memo]
575+ ?: ?=(?(@ [%clay %ford *]) product.clue)
576+ [ton memo]
577+ [ton (~(put by memo) [subject next.formula] product.ton)]
578+ =^ next memo
579+ =? trace
580+ ?=(?(%hunk %hand %lose %mean %spot) tag.formula)
581+ [[tag.formula product.clue] trace]
582+ $(formula next.formula)
583+ :_ memo
584+ ?. ?=(%0 -.next) next
585+ :- %0
586+ .* subject
587+ [11 [tag.formula 1 product.clue] 1 product.next]
588+ ==
589+ ::
590+ ++ frag
591+ |= [axis=@ noun=*]
592+ ^- (unit)
593+ ?: =(0 axis) ~
594+ |- ^- (unit)
595+ ?: =(1 axis) `noun
596+ ?@ noun ~
597+ =/ pick (cap axis)
598+ %= $
599+ axis (mas axis)
600+ noun ?-(pick %2 -.noun, %3 +.noun)
601+ ==
602+ ::
603+ ++ edit
604+ |= [axis=@ target=* value=*]
605+ ^- (unit)
606+ ?: =(1 axis) `value
607+ ?@ target ~
608+ =/ pick (cap axis)
609+ =/ mutant
610+ %= $
611+ axis (mas axis)
612+ target ?-(pick %2 -.target, %3 +.target)
613+ ==
614+ ?~ mutant ~
615+ ?- pick
616+ %2 `[u.mutant +.target]
617+ %3 `[-.target u.mutant]
618+ ==
619+ --
138620--
base-desk/lib/ring.hoon+46−45
@@ -18,10 +18,10 @@
1818 ::
1919 ++ generate-public-linkage
2020 |= link-scope=@
21− ^- [data=@ h=@udpoint]
21+ ^- [data=@ h=@uxpoint]
2222 ::
2323 =/ data=@ (mod link-scope l:ed:crypto)
24− =/ h=@udpoint (scalarmult-base:ed:crypto data)
24+ =/ h=@uxpoint (scalarmult-base:ed:crypto data)
2525 [data h]
2626 :: +generate-linkage: linkage information from scope and private key
2727 ::
@@ -30,13 +30,13 @@
3030 :: y: y = [x] * h
3131 ++ generate-linkage
3232 |= [link-scope=(unit @) my-private-key=@]
33− ^- (unit [data=@ h=@udpoint y=@udpoint])
33+ ^- (unit [data=@ h=@uxpoint y=@uxpoint])
3434 ::
3535 ?~ link-scope
3636 ~
3737 ::
38− =+ [data=@ h=@udpoint]=(generate-public-linkage u.link-scope)
39− =/ y=@udpoint (scalarmult:ed:crypto my-private-key h)
38+ =+ [data=@ h=@uxpoint]=(generate-public-linkage u.link-scope)
39+ =/ y=@uxpoint (scalarmult:ed:crypto my-private-key h)
4040 [~ data h y]
4141 :: +generate-challenge: generate challenge from a given message
4242 ::
@@ -47,13 +47,13 @@
4747 ++ generate-challenge
4848 |= $: :: common to both linked and unlinked
4949 message=@
50− g=@udpoint
50+ g=@uxpoint
5151 :: high level universal state
5252 ::
53− link-state=(unit [data=@ h=@udpoint y=@udpoint])
53+ link-state=(unit [data=@ h=@uxpoint y=@uxpoint])
5454 :: point to include in challenge when link-state isn't ~
5555 ::
56− h=(unit @udpoint)
56+ h=(unit @uxpoint)
5757 ==
5858 ^- @
5959 :: concatenate and reduce our message down to a 512-bit hash
@@ -74,9 +74,9 @@
7474 :: +generate-challenges: generates the full list of challenges
7575 ::
7676 ++ generate-challenges
77− |= $: link-state=(unit [data=@ h=@udpoint y=@udpoint])
77+ |= $: link-state=(unit [data=@ h=@uxpoint y=@uxpoint])
7878 message=@
79− public-keys=(list @udpoint)
79+ public-keys=(list @uxpoint)
8080 ss=(list @)
8181 ::
8282 prev-k=@u
@@ -86,14 +86,14 @@
8686 ==
8787 ^- (list @)
8888 ::
89− =/ gs=@udpoint
89+ =/ gs=@uxpoint
9090 %- add-scalarmult-scalarmult-base:ed:crypto :*
9191 prev-ch
9292 (snag prev-k public-keys)
9393 prev-s
9494 ==
9595 ::
96− =/ hs=(unit @udpoint)
96+ =/ hs=(unit @uxpoint)
9797 ?~ link-state
9898 ~
9999 ::
@@ -125,8 +125,8 @@
125125 :: used to generate the (unit point) consumed by +generate-challenge.
126126 ::
127127 ++ scalarmult-h
128− |= [u=@ linkage=(unit [data=@ h=@udpoint y=@udpoint])]
129− ^- (unit @udpoint)
128+ |= [u=@ linkage=(unit [data=@ h=@uxpoint y=@uxpoint])]
129+ ^- (unit @uxpoint)
130130 ?~ linkage
131131 ~
132132 [~ (scalarmult:ed:crypto u h.u.linkage)]
@@ -143,9 +143,9 @@
143143 |= $: message=@
144144 link-scope=(unit @)
145145 ::
146− anonymity-set=(set @udpoint)
147− my-public-key=@udpoint
148− my-private-key=@udscalar
146+ anonymity-set=(set @uxpoint)
147+ my-public-key=@uxpoint
148+ my-private-key=@uxscalar
149149 ::
150150 eny=@uvJ
151151 ==
@@ -157,7 +157,7 @@
157157 (need (find [my-public-key ~] anonymity-list))
158158 :: Generate linkage information if given
159159 ::
160− =/ linkage=(unit [data=@ h=@udpoint y=@udpoint])
160+ =/ linkage=(unit [data=@ h=@uxpoint y=@uxpoint])
161161 (generate-linkage link-scope my-private-key)
162162 :: initialize our random number generator from entropy
163163 ::
@@ -237,7 +237,7 @@
237237 |= $: message=@
238238 link-scope=(unit @)
239239 ::
240− anonymity-set=(set @udpoint)
240+ anonymity-set=(set @uxpoint)
241241 signature=raw-ring-signature
242242 ==
243243 ^- ?
@@ -259,14 +259,14 @@
259259 =/ s2-to-end=(list @) t.t.s.signature
260260 :: anonymity-list: set of public keys listified in ring order
261261 ::
262− =/ anonymity-list=(list @udpoint)
262+ =/ anonymity-list=(list @uxpoint)
263263 ~(tap in anonymity-set)
264264 :: participants: length of :anonymity-list
265265 ::
266266 =/ participants=@u
267267 (lent anonymity-list)
268268 ::
269− =/ z0p=@udpoint
269+ =/ z0p=@uxpoint
270270 %- add-scalarmult-scalarmult-base:ed:crypto :*
271271 ch0.signature
272272 (head anonymity-list)
@@ -275,14 +275,14 @@
275275 :: generate the linkage using public data, and the y point from the
276276 :: signature
277277 ::
278− =/ linkage=(unit [data=@ h=@udpoint y=@udpoint])
278+ =/ linkage=(unit [data=@ h=@uxpoint y=@uxpoint])
279279 ?~ link-scope
280280 ~
281− =+ [data=@ h=@udpoint]=(generate-public-linkage u.link-scope)
281+ =+ [data=@ h=@uxpoint]=(generate-public-linkage u.link-scope)
282282 :- ~
283283 [data h (need y.signature)]
284284 ::
285− =/ z0pp=(unit @udpoint)
285+ =/ z0pp=(unit @uxpoint)
286286 ?~ linkage
287287 ~
288288 :- ~
@@ -319,7 +319,7 @@
319319 :: +seed-to-private-key-scalar: keyfile form to scalar we can multiply with
320320 ::
321321 ++ seed-to-private-key-scalar
322− |= sk=@I ^- @udscalar
322+ |= sk=@I ^- @uxscalar
323323 ?: (gth (met 3 sk) 32) !!
324324 =+ h=(shal (rsh [0 3] b:ed:crypto) sk)
325325 %+ add
@@ -347,44 +347,45 @@
347347 ::
348348 ++ ship-life-to-pubid
349349 |= [our=@p now=@da ship=@p =life]
350− ^- @udpoint
350+ ^- @uxpoint
351351 ::
352− =/ d=[=^life =pass]
352+ =/ d=[=^life =pass *]
353353 =/ scry-path=path
354− :~ %k
354+ :~ %j
355355 (scot %p our)
356+ %deed
356357 (scot %da now)
357358 (scot %p ship)
358359 (scot %ud life)
359360 ==
360− .^([^life pass] scry-path)
361+ .^([^life pass *] scry-path)
361362 :: we have the deed which has pass, which is several numbers +cat-ed
362363 :: together; pull out the keys
363364 ::
364365 =/ x=[crypt=@ auth=@] (get-public-key-from-pass pass.d)
365366 ::
366− `@udpoint`auth.x
367+ `@uxpoint`auth.x
367368 ::
368369 ++ build-signing-participants
369370 |= [our=@p now=@da invited=(list @p)]
370− ^- [(set [@p life]) (set @udpoint)]
371+ ^- [(set [@p life]) (set @uxpoint)]
371372 ::
372373 =| participants=(set [@p life])
373− =| keys=(set @udpoint)
374+ =| keys=(set @uxpoint)
374375 ::
375376 |-
376377 ?~ invited
377378 [participants keys]
378379 ::
379− =/ =life
380− .^(life k+/(scot %p our)/life/(scot %da now)/(scot %p i.invited))
380+ =/ lyfe=(unit @ud)
381+ .^((unit @ud) j+/(scot %p our)/lyfe/(scot %da now)/(scot %p i.invited))
381382 ::
382− ?: =(life 0)
383+ ?~ lyfe
383384 $(invited t.invited)
384385 ::
385− =/ pubkey=@udpoint (ship-life-to-pubid our now i.invited life)
386+ =/ pubkey=@uxpoint (ship-life-to-pubid our now i.invited u.lyfe)
386387 ::
387− =. participants (~(put in participants) [i.invited life])
388+ =. participants (~(put in participants) [i.invited u.lyfe])
388389 =. keys (~(put in keys) pubkey)
389390 ::
390391 $(invited t.invited)
@@ -392,15 +393,15 @@
392393 ::
393394 ++ build-verifying-participants
394395 |= [our=@p now=@da invited=(list [ship=@p =life])]
395− ^- (set @udpoint)
396+ ^- (set @uxpoint)
396397 ::
397− =| keys=(set @udpoint)
398+ =| keys=(set @uxpoint)
398399 ::
399400 |-
400401 ?~ invited
401402 keys
402403 ::
403− =/ pubkey=@udpoint
404+ =/ pubkey=@uxpoint
404405 (ship-life-to-pubid our now ship.i.invited life.i.invited)
405406 =. keys
406407 (~(put in keys) pubkey)
@@ -431,23 +432,23 @@
431432 =/ link-hash=(unit @) (bind link-scope |=(a=* (shaz (jam a))))
432433 :: get everyone's public keys
433434 ::
434− =/ p=[participants=(set [ship=@p =life]) keys=(set @udpoint)]
435+ =/ p=[participants=(set [ship=@p =life]) keys=(set @uxpoint)]
435436 (build-signing-participants:detail our now ~(tap in anonymity-set))
436437 :: get our ships' current life
437438 ::
438439 =/ our-life=life
439− .^(life %k /(scot %p our)/life/(scot %da now)/(scot %p our))
440+ .^(life %j /(scot %p our)/life/(scot %da now)/(scot %p our))
440441 :: get our ships' secret keyfile ring
441442 ::
442443 =/ secret-ring=ring
443− .^(ring %k /(scot %p our)/vein/(scot %da now)/(scot %ud our-life))
444+ .^(ring %j /(scot %p our)/vein/(scot %da now)/(scot %ud our-life))
444445 :: fetch the encoded auth seed from the ring
445446 ::
446447 =/ secret-auth-seed=@
447448 +:(get-private-key-from-ring:detail secret-ring)
448449 :: get our ships' public key
449450 ::
450− =/ public-key=@udpoint
451+ =/ public-key=@uxpoint
451452 (ship-life-to-pubid:detail our now our our-life)
452453 ::
453454 :- participants.p
@@ -466,7 +467,7 @@
466467 |= [our=@p now=@da message=* =ring-signature]
467468 ^- ?
468469 ::
469− =/ keys=(set @udpoint)
470+ =/ keys=(set @uxpoint)
470471 %^ build-verifying-participants:detail our now
471472 ~(tap in participants.ring-signature)
472473 ::
base-desk/lib/server.hoon+2−2
@@ -19,7 +19,7 @@
1919++ json-to-octs
2020 |= jon=json
2121 ^- octs
22− (as-octt:mimes:html (en-json:html jon))
22+ (as-octs:mimes:html (en:json:html jon))
2323::
2424++ app
2525 |%
@@ -114,7 +114,7 @@
114114 :_ `octs
115115 [200 [['content-type' 'image/svg+xml'] ?:(cache [max-1-wk ~] ~)]]
116116 ::
117− ++ ico-response
117+ ++ ico-response
118118 |= =octs
119119 ^- simple-payload:http
120120 [[200 [['content-type' 'image/x-icon'] max-1-wk ~]] `octs]
base-desk/lib/shoe.hoon+72−36
@@ -13,15 +13,15 @@
1313/- *sole
1414/+ sole, auto=language-server-complete
1515|%
16−+$ state-0
17− $: %0
18− soles=(map @ta sole-share)
16++$ state-2
17+ $: %2
18+ soles=(map sole-id sole-share)
1919 ==
2020:: $card: standard gall cards plus shoe effects
2121::
2222+$ card
2323 $% card:agent:gall
24− [%shoe sole-ids=(list @ta) effect=shoe-effect] :: ~ sends to all soles
24+ [%shoe sole-ids=(list sole-id) effect=shoe-effect] :: ~ sends to all
2525 ==
2626:: $shoe-effect: easier sole-effects
2727::
@@ -47,30 +47,30 @@
4747 :: if the head of the result is true, instantly run the command
4848 ::
4949 ++ command-parser
50− |~ sole-id=@ta
50+ |~ =sole-id
5151 |~(nail *(like [? command-type]))
5252 :: +tab-list: autocomplete options for the session (to match +command-parser)
5353 ::
5454 ++ tab-list
55− |~ sole-id=@ta
55+ |~ =sole-id
5656 :: (list [@t tank])
5757 *(list (option:auto tank))
5858 :: +on-command: called when a valid command is run
5959 ::
6060 ++ on-command
61− |~ [sole-id=@ta command=command-type]
61+ |~ [=sole-id command=command-type]
6262 *(quip card _^|(..on-init))
6363 ::
6464 ++ can-connect
65− |~ sole-id=@ta
65+ |~ =sole-id
6666 *?
6767 ::
6868 ++ on-connect
69− |~ sole-id=@ta
69+ |~ =sole-id
7070 *(quip card _^|(..on-init))
7171 ::
7272 ++ on-disconnect
73− |~ sole-id=@ta
73+ |~ =sole-id
7474 *(quip card _^|(..on-init))
7575 ::
7676 ::NOTE standard gall agent arms below, though they may produce %shoe cards
@@ -119,27 +119,27 @@
119119 |* [shoe=* command-type=mold]
120120 |_ =bowl:gall
121121 ++ command-parser
122− |= sole-id=@ta
122+ |= =sole-id
123123 (easy *[? command-type])
124124 ::
125125 ++ tab-list
126− |= sole-id=@ta
126+ |= =sole-id
127127 ~
128128 ::
129129 ++ on-command
130− |= [sole-id=@ta command=command-type]
130+ |= [=sole-id command=command-type]
131131 [~ shoe]
132132 ::
133133 ++ can-connect
134− |= sole-id=@ta
134+ |= =sole-id
135135 (team:title [our src]:bowl)
136136 ::
137137 ++ on-connect
138− |= sole-id=@ta
138+ |= =sole-id
139139 [~ shoe]
140140 ::
141141 ++ on-disconnect
142− |= sole-id=@ta
142+ |= =sole-id
143143 [~ shoe]
144144 --
145145:: +agent: creates wrapper core that handles sole events and calls shoe arms
@@ -147,7 +147,7 @@
147147++ agent
148148 |* command-type=mold
149149 |= =(shoe command-type)
150− =| state-0
150+ =| state-2
151151 =* state -
152152 ^- agent:gall
153153 =>
@@ -164,8 +164,7 @@
164164 %+ turn
165165 ?^ sole-ids.card sole-ids.card
166166 ~(tap in ~(key by soles))
167− |= sole-id=@ta
168− /sole/[sole-id]
167+ id-to-path:sole
169168 ::
170169 %table
171170 =; fez=(list sole-effect)
@@ -189,7 +188,7 @@
189188 =^ cards shoe on-init:og
190189 [(deal cards) this]
191190 ::
192− ++ on-save !>([%shoe-app on-save:og state])
191+ ++ on-save :(slop !>(%shoe-app) on-save:og !>(state))
193192 ::
194193 ++ on-load
195194 |= old-state=vase
@@ -202,9 +201,45 @@
202201 ?. ?=([%shoe-app ^] q.old-state)
203202 =^ cards shoe (on-load:og old-state)
204203 [(deal cards) this]
205− =^ old-inner state +:!<([%shoe-app vase state-0] old-state)
206− =^ cards shoe (on-load:og old-inner)
207− [(deal cards) this]
204+ |^ :: versions %0 and %1 stored the inner state double-vased.
205+ :: fixing this coincided with the 408 type-of-type migration.
206+ ::
207+ ?: ?=([%shoe-app * ?(%0 %1) *] q.old-state)
208+ =| old-outer=state-any
209+ =^ old-inner old-outer
210+ +:!<([%shoe-app vase:h136 state-any] old-state)
211+ =^ caz shoe (on-load:og (next-vase:h136 old-inner))
212+ =^ cuz old-outer
213+ ?. ?=(%0 -.old-outer) [~ old-outer]
214+ (state-0-to-1 old-outer)
215+ =? old-outer ?=(%1 -.old-outer) (state-1-to-2 old-outer)
216+ ?> ?=(%2 -.old-outer)
217+ [(weld cuz (deal caz)) this(state old-outer)]
218+ ::
219+ =+ !<(old=state-any (slot 7 old-state))
220+ ?> ?=(%2 -.old)
221+ =. state old
222+ ::
223+ =^ caz shoe (on-load:og (slot 6 old-state))
224+ [(deal caz) this]
225+ ::
226+ +$ state-any $%(state-2 state-1 state-0)
227+ +$ state-1 _%*(. *state-2 - %1)
228+ +$ state-0 [%0 soles=(map @ta sole-share)]
229+ ++ state-1-to-2 |=(old=state-1 old(- %2))
230+ ++ state-0-to-1
231+ |= old=state-0
232+ ^- (quip card:agent:gall state-1)
233+ :- %+ turn ~(tap in ~(key by soles.old))
234+ |= id=@ta
235+ ^- card:agent:gall
236+ [%give %kick ~[/sole/[id]] ~]
237+ :- %1
238+ %- ~(gas by *(map sole-id sole-share))
239+ %+ murn ~(tap by soles.old)
240+ |= [id=@ta s=sole-share]
241+ (bind (upgrade-id:sole id) (late s))
242+ --
208243 ::
209244 ++ on-poke
210245 |= [=mark =vase]
@@ -326,19 +361,18 @@
326361 ++ on-watch
327362 |= =path
328363 ^- (quip card:agent:gall agent:gall)
329− ?. ?=([%sole @ ~] path)
364+ ?~ sole-id=(path-to-id:sole path)
330365 =^ cards shoe
331366 (on-watch:og path)
332367 [(deal cards) this]
333− =* sole-id i.t.path
334− ?> (can-connect:og sole-id)
335− =. soles (~(put by soles) sole-id *sole-share)
368+ ?> (can-connect:og u.sole-id)
369+ =. soles (~(put by soles) u.sole-id *sole-share)
336370 =^ cards shoe
337− (on-connect:og sole-id)
371+ (on-connect:og u.sole-id)
338372 :_ this
339373 %- deal
340374 :_ cards
341− [%shoe [sole-id]~ %sole %pro & dap.bowl "> "]
375+ [%shoe [u.sole-id]~ %sole %pro & dap.bowl "> "]
342376 ::
343377 ++ on-leave
344378 |= =path
@@ -388,23 +422,25 @@
388422 =/ cobs=(list [wid=@ud (list tape)])
389423 (turn cows col-as-lines)
390424 =+ [lin=0 any=|]
425+ =+ len=(lent cobs)
391426 =| fez=(list sole-effect)
392427 |- ^+ fez
393− =; out=tape
428+ =; [line=(list tape) end=@ud]
394429 :: done when we're past the end of all columns
395430 ::
396− ?: (levy out (cury test ' '))
431+ ?: =(len end)
397432 (flop fez)
398433 =; fec=sole-effect
399434 $(lin +(lin), fez [fec fez])
435+ =/ out=tape
436+ (zing (join " " line))
400437 ?. bold txt+out
401438 klr+[[`%br ~ ~]^[(crip out)]~]~
402− %+ roll cobs
403− |= [[wid=@ud lines=(list tape)] out=tape]
404− %+ weld out
405− %+ weld ?~(out "" " ")
439+ %^ spin cobs 0
440+ |= [[wid=@ud lines=(list tape)] empty=@ud]
406441 =+ l=(swag [lin 1] lines)
407− ?^(l i.l (reap wid ' '))
442+ ?^ l [i.l empty]
443+ [(reap wid ' ') +(empty)]
408444 ::
409445 ++ col-as-lines
410446 |= [wid=@ud col=dime]
base-desk/lib/sink.hoonnew file+26
@@ -0,0 +1,26 @@
1+/+ noun-diff
2+|%
3+++ clog
4+ |$ [stut]
5+ $%
6+ [%flush stut]
7+ [%drain patch:noun-diff]
8+ ==
9+++ sink
10+ |* pats=(list path)
11+ |* stat=*
12+ |@
13+ ++ sync
14+ |= [stat=_stat]
15+ ^- [card:agent:gall _..sync]
16+ =/ dif
17+ %+ diff:noun-diff ^stat stat
18+ :-
19+ [%give %fact pats %noun !>(^-((clog) [%drain dif]))]
20+ ..sync(stat stat)
21+ ++ paths pats
22+ ++ flush
23+ ^- card:agent:gall
24+ [%give %fact pats %noun !>(^-((clog) [%flush stat]))]
25+ --
26+--
base-desk/lib/sole.hoon+24
@@ -136,4 +136,28 @@
136136 =+ dat=(transmute [%mor leg] [%ins pos `@c`0])
137137 ?> ?=(%ins -.dat)
138138 p.dat
139+::
140+::
141+++ path-to-id
142+ |= =path
143+ ^- (unit sole-id)
144+ ?. ?=([%sole @ ?(~ [@ ~])] path) ~
145+ ?~ who=(slaw %p i.t.path) ~
146+ `[u.who ?~(t.t.path %$ i.t.t.path)]
147+::
148+++ id-to-path
149+ |= sole-id
150+ ^- path
151+ ::TODO this whole "no empty path ending" business feels icky.
152+ :: do we want default session to be ~.~ ?
153+ :: concern here is that outsiders cannot subscribe to the default
154+ :: session, because /sole/~zod/ isn't a valid path...
155+ [%sole (scot %p who) ?~(ses ~ /[ses])]
156+::
157+++ upgrade-id
158+ |= old=@ta
159+ ^- (unit sole-id)
160+ %+ rush old
161+ %+ cook (late %$)
162+ ;~(pfix (jest 'drum_~') fed:ag)
139163--
base-desk/lib/sss.hoonnew file+445
@@ -0,0 +1,445 @@
1+/- *sss
2+/+ *mip
3+::
4+|%
5+++ mk-subs :: Create sub-map.
6+ |* [=(lake) paths=mold]
7+ -:+6:(da lake paths)
8+::
9+++ mk-pubs :: Create pub-map.
10+ |* [=(lake) paths=mold]
11+ -:+6:(du lake paths)
12+::
13+++ mk-mar :: Create mar.
14+ |* =(lake)
15+ |_ =(response:poke lake *)
16+ ++ grow
17+ |%
18+ ++ noun response
19+ --
20+ ++ grab
21+ |%
22+ ++ noun (response:poke lake *)
23+ --
24+ ++ grad %noun
25+ --
26+++ fled :: Like +sped but head is a path.
27+ |= vax=vase
28+ ^- vase
29+ :_ q.vax
30+ %- ~(play ut p.vax)
31+ =- [%wtgr [%wtts - [%& 2]~] [%$ 1]]
32+ =/ pax ~| %path-none ;;(path -.q.vax)
33+ |- ^- spec
34+ ?~ pax [%base %null]
35+ [%bccl ~[[%leaf %ta -.pax] $(pax +.pax)]]
36+::
37+++ zoom |= =noun ~| %need-path $/sss/;;(path noun)
38+::
39+++ da :: Manage subscriptions.
40+ |* [=(lake) paths=mold]
41+ =>
42+ |%
43+ +$ from (on-rock:poke lake paths)
44+ +$ into (response:poke lake paths)
45+ +$ result (request:poke paths)
46+ +$ fail [paths ship dude]
47+ +$ flow [=aeon stale=_| fail=_| =rock:lake]
48+ +$ subs [%0 (map [ship dude paths] (unit flow))]
49+ --
50+ |= $: sub=subs
51+ =bowl:gall
52+ result-type=type
53+ on-rock-type=type
54+ fail-type=type
55+ ==
56+ => .(sub +.sub)
57+ |%
58+ ++ surf :: Subscribe to [ship dude path].
59+ |= which=[ship dude paths]
60+ ^- (quip card:agent:gall subs)
61+ ?+ flow=(~(get by sub) which) `0/sub
62+ ~ [~[(pine which)] 0/(~(put by sub) which ~)]
63+ [~ ~] [~[(pine which)] 0/sub]
64+ [~ ~ [* %& * *]] [~[(pine which)] 0/sub]
65+ ==
66+ ++ quit (corl (lead %0) ~(del by sub)) :: Unsub from [ship dude path].
67+ ++ read :: See current subscribed states.
68+ ^- (map [ship dude paths] [stale=? fail=? =rock:lake])
69+ %- malt %+ murn ~(tap by sub)
70+ |= [key=[ship dude paths] val=(unit flow)]
71+ ?~ val ~
72+ `[key +.u.val]
73+ :: :: Check poke-ack for errors.
74+ :: :: If an %sss-on-rock poke nacks,
75+ ++ chit :: that state is flagged as failed.
76+ |= [[aeon=term ship=term dude=term path=paths] =sign:agent:gall]
77+ ^- subs
78+ :- %0
79+ ?> ?=(%poke-ack -.sign)
80+ ?~ p.sign sub
81+ %+ ~(jab by sub) [(slav %p ship) dude path]
82+ |= (unit flow)
83+ =/ =flow (need +<)
84+ ?> =(aeon.flow (slav %ud aeon))
85+ `flow(fail &)
86+ :: :: Check poke-ack for errors.
87+ :: :: If a scry request nacks,
88+ ++ tell :: that state is flagged as stale.
89+ |= [[ship=term =dude aeon=term path=paths] =sign:agent:gall]
90+ ^- (quip card:agent:gall subs)
91+ ?> ?=(%poke-ack -.sign)
92+ ?~ p.sign `0/sub
93+ =/ current [ship=(slav %p ship) dude=dude path=path]
94+ ?+ flow=(~(get by sub) current) `0/sub
95+ [~ ~ *]
96+ =. stale.u.u.flow &
97+ :_ 0/(~(put by sub) current u.flow)
98+ ~[(on-rock-poke fake=& current u.u.flow ~)]
99+ ::
100+ [~ ~]
101+ :_ 0/(~(del by sub) current) :_ ~
102+ :* %pass (zoom surf-fail/aeon/ship/dude/path)
103+ %agent [our dap]:bowl
104+ %poke %sss-surf-fail fail-type ^- fail
105+ [path ship dude]:current
106+ ==
107+ ==
108+ ++ apply :: Handle response from publisher.
109+ |= res=(response:poke lake paths)
110+ ^- (quip card:agent:gall subs)
111+ =* current [src.bowl dude.res path.res]
112+ =/ old=flow (fall (~(got by sub) current) *flow)
113+ ?: ?=(%tomb what.res)
114+ =/ =flow old(stale &)
115+ :_ 0/(~(put by sub) current `flow) :_ ~
116+ (on-rock-poke fake=& current flow ~)
117+ ::
118+ =/ [wave=(unit wave:lake) new=(unit flow)]
119+ ?- what.res
120+ %rock ?: (lte aeon.res aeon.old) [~ ~]
121+ [~ `[aeon.res | | rock.res]]
122+ %wave ?: (lte aeon.res aeon.old) [~ ~]
123+ ?> =(aeon.res +(aeon.old))
124+ [`wave.res `[aeon.res | | (wash:lake rock.old wave.res)]]
125+ ==
126+ ?~ new `0/sub
127+ :_ 0/(~(put by sub) current new) :_ ~
128+ (on-rock-poke fake=& current u.new wave)
129+ ::
130+ ++ handle-fake-on-rock
131+ |= =(on-rock:poke lake paths)
132+ ^- (list card:agent:gall)
133+ ?~ flow=(~(get by sub) [src from path]:on-rock) ~
134+ ?~ u.flow ~
135+ ?. =([stale fail rock]:u.u.flow [stale fail rock]:on-rock) ~
136+ ~[(on-rock-poke fake=| [src from path]:on-rock u.u.flow wave.on-rock)]
137+ ::
138+ :: Non-public facing arms below
139+ ::
140+ ++ pine
141+ |= [who=ship which=dude where=paths]
142+ ^- card:agent:gall
143+ :* %pass (zoom scry-request/(scot %p who)^which^where)
144+ %agent [who which]
145+ %poke sss-to-pub/[result-type `result`[where dap.bowl]]
146+ ==
147+ ++ on-rock-poke
148+ |= [fake=? [=ship =dude path=paths] flow wave=(unit wave:lake)]
149+ ^- card:agent:gall
150+ :* %pass %+ zoom ?:(fake %fake %on-rock)
151+ (scot %ud aeon)^(scot %p ship)^dude^path
152+ %agent [our dap]:bowl
153+ %poke ?:(fake %sss-fake-on-rock %sss-on-rock)
154+ on-rock-type `from`[path ship dude stale fail rock wave]
155+ ==
156+ --
157+++ du :: Manage publications.
158+ |* [=(lake) paths=mold]
159+ =>
160+ |%
161+ +$ into (request:poke paths)
162+ +$ result (response:poke lake paths)
163+ +$ rule $~ [`5 5]
164+ [horizon=(unit @ud) frequency=@ud] :: Retention policy
165+ +$ tide
166+ $: rok=((mop aeon rock:lake) gte)
167+ wav=((mop aeon wave:lake) lte)
168+ rul=rule
169+ mem=(jug ship dude)
170+ ==
171+ +$ buoy
172+ $: tid=$~(*tide $@(aeon tide))
173+ alo=(unit (set ship))
174+ ==
175+ ++ pubs
176+ =< $>(%1 versioned)
177+ |%
178+ ++ update
179+ |= =versioned
180+ ^- pubs
181+ ?- -.versioned
182+ %1 versioned
183+ %0
184+ :- %1
185+ %- ~(run by +.versioned)
186+ |= =buoy-0:^versioned
187+ ^- buoy
188+ %= buoy-0
189+ tid
190+ ?@ tid.buoy-0 tid.buoy-0
191+ ^- tide
192+ %= tid.buoy-0
193+ rocks.rul
194+ ?: =(waves.rul.tid.buoy-0 0) ~
195+ `(mul [+(rocks) waves]:rul.tid.buoy-0)
196+ ::
197+ mem
198+ ^- (jug ship dude)
199+ %- ~(run by mem.tid.buoy-0)
200+ |= =(map dude @da)
201+ ^- (set dude)
202+ ~(key by map)
203+ ==
204+ ==
205+ ==
206+ ++ versioned
207+ =< $% [%0 (map paths buoy-0)]
208+ [%1 (map paths buoy)]
209+ ==
210+ |%
211+ +$ buoy-0
212+ $: tid=$~(*tide-0 $@(aeon tide-0))
213+ alo=(unit (set ship))
214+ ==
215+ +$ tide-0
216+ $: rok=((mop aeon rock:lake) gte)
217+ wav=((mop aeon wave:lake) lte)
218+ rul=[rocks=@ud waves=@ud]
219+ mem=(mip ship dude @da)
220+ ==
221+ --
222+ --
223+ --
224+ |= [pub=versioned:pubs =bowl:gall result-type=type]
225+ => .(pub +:(update:pubs pub))
226+ =* rok ((on aeon rock:lake) gte)
227+ =* wav ((on aeon wave:lake) lte)
228+ |%
229+ ++ rule :: Set new retention policy.
230+ |= [path=paths =^rule]
231+ ^- pubs
232+ :- %1
233+ %- fall :_ (~(put by pub) path %*(. *$<(aeon buoy) rul.tid rule))
234+ %- mole |.
235+ %+ ~(jab by pub) path
236+ |= =buoy
237+ ?@ tid.buoy buoy
238+ buoy(tid (form tid.buoy(rul rule)))
239+ ::
240+ ++ wipe :: Create new rock and wipe rest.
241+ |= path=paths
242+ ^- pubs
243+ :- %1
244+ %+ ~(jab by pub) path
245+ |= =buoy
246+ ?@ tid.buoy buoy
247+ %* . buoy(tid (form tid.buoy(rul [`0 1])))
248+ rul.tid rul.tid.buoy
249+ wav.tid ~
250+ ==
251+ ++ give :: Give a wave on a path.
252+ |= [path=paths =wave:lake]
253+ ^- (quip card:agent:gall pubs)
254+ ?~ ((soft ^path) path) ~| %need-path !!
255+ =/ buoy (~(gut by pub) path *buoy)
256+ =? buoy ?=(@ tid.buoy)
257+ %*(. buoy(tid *tide) rok.tid (put:rok ~ +(tid.buoy) *rock:lake))
258+ ?> ?=(^ tid.buoy)
259+ =* tide tid.buoy
260+ =/ next=aeon +((latest tide))
261+ :- %- zing
262+ %+ turn ~(tap by mem.tide)
263+ |= [=ship =(set dude)]
264+ %+ turn ~(tap in set)
265+ |= =dude
266+ (send wave/[next wave] ship dude path)
267+ :- %1
268+ %+ ~(put by pub) path
269+ =/ last=[=aeon =rock:lake] (fall (pry:rok rok.tide) *[key val]:rok)
270+ =. wav.tide (put:wav wav.tide next wave)
271+ =. mem.tide ~
272+ ?. =(next (add aeon.last frequency.rul.tide)) buoy
273+ buoy(tid (form tide))
274+ ::
275+ ++ fork :: Fork a pub into an empty path.
276+ |= [from=paths to=paths]
277+ ^- pubs
278+ :- %1
279+ ?< (~(has by pub) to)
280+ (~(put by pub) to (~(got by pub) from))
281+ ::
282+ ++ copy :: Fork a sub into an empty path.
283+ |= [sub=_(mk-subs lake *) from=[ship dude *] to=paths]
284+ ^- pubs
285+ :- %1
286+ ?< (~(has by pub) to)
287+ %+ ~(put by pub) to
288+ %* . *$<(aeon buoy)
289+ rok.tid (put:rok ~ [aeon rock]:(need (~(got by +:sub) from)))
290+ ==
291+ ::
292+ ++ perm :: Change permissions with gate.
293+ |= [where=(list paths) diff=$-((unit (set ship)) (unit (set ship)))]
294+ ^- (quip card:agent:gall pubs)
295+ %+ edit where
296+ |= =buoy
297+ =/ new=_alo.buoy (diff alo.buoy)
298+ ?@ tid.buoy buoy(alo new)
299+ %= buoy
300+ alo new
301+ mem.tid ?~ new mem.tid.buoy
302+ %. mem.tid.buoy
303+ ~(int by (malt (turn ~(tap in u.new) (late *(set @)))))
304+ ==
305+ ++ public (curr perm _~) :: Make list of paths public.
306+ ++ secret (curr perm _`~) :: Make list of paths secret.
307+ :: :: Block ships from paths.
308+ ++ block :: No-ops on public paths.
309+ |= [who=(list ship) whence=(list paths)]
310+ ^- (quip card:agent:gall pubs)
311+ %+ perm whence
312+ |= old=(unit (set ship))
313+ ?~ old ~ `(~(dif in u.old) (sy who))
314+ :: :: Allow ships to paths.
315+ ++ allow :: Any public paths will no-op.
316+ |= [who=(list ship) where=(list paths)]
317+ ^- (quip card:agent:gall pubs)
318+ %+ perm where
319+ |= old=(unit (set ship))
320+ ?~ old ~ `(~(gas in u.old) who)
321+ :: :: Kill a list of paths, i.e. tell
322+ ++ kill :: subs to not expect updates.
323+ (curr edit |=(=buoy buoy(tid (latest tid.buoy))))
324+ :: :: Reopen list of killed paths.
325+ ++ read :: See current published states.
326+ ^- (map paths [allowed=(unit (set ship)) =rock:lake])
327+ %- malt %+ murn ~(tap by pub)
328+ |= [path=paths =buoy]
329+ ^- (unit [paths (unit (set ship)) rock:lake])
330+ ?@ tide=tid.buoy ~
331+ :^ ~ path alo.buoy =< rock
332+ =/ snap=[=aeon =rock:lake] (fall (pry:rok rok.tide) *[key val]:rok)
333+ %+ roll (tap:wav (lot:wav wav.tide `aeon.snap ~))
334+ |= [[=aeon =wave:lake] =_snap]
335+ ?. =(aeon +(aeon.snap)) snap
336+ [aeon (wash:lake rock.snap wave)]
337+ ::
338+ ++ apply :: Handle request from subscriber.
339+ |= req=(request:poke paths)
340+ ^- (quip card:agent:gall pubs)
341+ =/ =buoy (~(gut by pub) path.req *buoy)
342+ ?< &(?=(^ alo.buoy) !(~(has in u.alo.buoy) src.bowl))
343+ ?@ tid.buoy
344+ :_ 1/pub :_ ~
345+ (send tomb/~ src.bowl dude.req path.req)
346+ :_ 1/pub :_ ~
347+ =/ last (fall (pry:rok rok.tid.buoy) *[=key =val]:rok)
348+ (send rock/last src.bowl dude.req path.req)
349+ ::
350+ ++ tell
351+ |= [[ship=term =dude aeon=term path=paths] =sign:agent:gall]
352+ ^- (quip card:agent:gall pubs)
353+ ?> ?=(%poke-ack -.sign)
354+ ?^ p.sign `1/pub
355+ =/ =buoy (~(gut by pub) path *buoy)
356+ ?< &(?=(^ alo.buoy) !(~(has in u.alo.buoy) src.bowl))
357+ ?@ tid.buoy
358+ :_ 1/pub :_ ~
359+ (send tomb/~ src.bowl dude path)
360+ ::
361+ => .(aeon +((slav %ud aeon)))
362+ ?^ dat=(get:wav wav.tid.buoy aeon)
363+ :_ 1/pub :_ ~
364+ (send wave/[aeon u.dat] src.bowl dude path)
365+ =/ last (fall (pry:rok rok.tid.buoy) [=key =val]:rok)
366+ ?: (lte aeon key.last)
367+ :_ 1/pub :_ ~
368+ (send rock/last src.bowl dude path)
369+ :- ~
370+ :- %1
371+ %+ ~(put by pub) path
372+ %= buoy
373+ mem.tid (~(put ju mem.tid.buoy) src.bowl dude)
374+ ==
375+ ::
376+ :: Non-public facing arms below
377+ ::
378+ ++ send
379+ |= [payload=_|2:*(response:poke lake paths) =ship =dude path=paths]
380+ ^- card:agent:gall
381+ =* mark (cat 3 %sss- name:lake)
382+ =/ callback=^path
383+ ?: ?=(%tomb what.payload) (zoom tomb-response/(scot %p ship)^dude^path)
384+ (zoom scry-response/(scot %p ship)^dude^(scot %ud aeon.payload)^path)
385+ :* %pass callback
386+ %agent [ship dude]
387+ %poke mark result-type ^- (response:poke lake paths)
388+ [path dap.bowl payload]
389+ ==
390+ ++ latest
391+ |= =$@(aeon tide)
392+ ^- aeon
393+ ?@ tide tide
394+ %+ max (fall (bind (pry:rok rok.tide) head) 0)
395+ (fall (bind (ram:wav wav.tide) head) 0)
396+ ::
397+ ++ edit
398+ |= [ps=(list paths) edit=$-(buoy buoy)]
399+ ^- (quip card:agent:gall pubs)
400+ %- ~(rep in (sy ps))
401+ |= [path=paths caz=(list card:agent:gall) %1 =_pub]
402+ ?~ old=(~(get by pub) path) [caz 1/pub]
403+ =/ new=buoy (edit u.old)
404+ :_ 1/(~(put by pub) path new)
405+ %- weld :_ caz
406+ ^- (list card:agent:gall)
407+ ?@ tid.u.old ~
408+ ?@ tid.new
409+ %- zing
410+ %+ turn ~(tap by mem.tid.u.old)
411+ |= [=ship =(set dude)]
412+ (turn ~(tap in set) |=(=dude (send tomb/~ ship dude path)))
413+ ?~ alo.new ~
414+ =/ new-alo=(jug ship dude)
415+ (malt (turn ~(tap in u.alo.new) (late *(set @))))
416+ %- zing
417+ %+ turn ~(tap by (~(dif by mem.tid.u.old) new-alo))
418+ |= [=ship =(set dude)]
419+ (turn ~(tap in set) |=(=dude (send tomb/~ ship dude path)))
420+ ::
421+ ++ form
422+ |= =tide
423+ ^+ tide
424+ =/ max-rock=[=aeon =rock:lake] (fall (pry:rok rok.tide) *[key val]:rok)
425+ =/ max-wave (fall (bind (ram:wav wav.tide) head) 0)
426+ =? rok.tide :: Create new rock.
427+ ?& !=(frequency.rul.tide 0)
428+ (gte max-wave (add aeon.max-rock frequency.rul.tide))
429+ ==
430+ %+ put:rok rok.tide
431+ %+ roll (tab:wav wav.tide `aeon.max-rock max-wave)
432+ |: [*[now=aeon =wave:lake] `[prev=aeon =rock:lake]`max-rock]
433+ ~| %aeon-awry
434+ ?> =(now +(prev))
435+ [now (wash:lake rock wave)]
436+ =. rok.tide
437+ ?~ horizon.rul.tide :: Only keep genesis and latest.
438+ (gas:rok ~ (murn ~[(ram:rok rok.tide) (pry:rok rok.tide)] same))
439+ %^ lot:rok rok.tide :: Delete beyond horizon.
440+ ~
441+ (mole |.((sub max-wave (max [u.horizon frequency]:rul.tide))))
442+ ~| %rock-zero
443+ tide(wav (lot:wav wav.tide (bind (ram:rok rok.tide) |=([r=@ *] (dec r))) ~))
444+ --
445+--
base-desk/lib/story.hoonnew file+88
@@ -0,0 +1,88 @@
1+/- *story
2+!:
3+^?
4+|%
5+:: XX generalize move to hoon.hoon
6+++ dif-ju
7+ |= [a=story b=story]
8+ ^- story
9+ :: if 0 is the empty set,
10+ :: a \ 0 = a
11+ :: 0 \ b = 0 :: anything in 0 but not in b is by definition 0
12+ ::
13+ ?: =(~ a) ~
14+ :: uno := (a-b) + (merged items in both a and b) + (b-a)
15+ :: ret := (a-b) + (merged items in both a and b)
16+ :: ret = (~(int by a) uno) :: preserve only the entries whose keys are in a
17+ =/ uno=story
18+ %- (~(uno by a) b)
19+ |= [k=tako:clay proses-a=proses proses-b=proses]
20+ ^- proses
21+ (~(dif in proses-a) proses-b)
22+ ::
23+ =/ ret=story (~(int by a) uno)
24+ :: normalizing step, remove any keys with null sets,
25+ :: which can occur if proses-a == proses-b above
26+ %- ~(gas by *story)
27+ (skip ~(tap by ret) |=([k=* v=proses] ?=(~ v)))
28+::
29+++ uni-ju
30+ |= [a=story b=story]
31+ ^- story
32+ :: 0 + b = b
33+ ?: =(~ a) b
34+ %- (~(uno by a) b)
35+ |= [k=tako:clay proses-a=proses proses-b=proses]
36+ ^- proses
37+ (~(uni in proses-a) proses-b)
38+::
39+:: Canonical textual representation
40+::
41+++ chapter-to-text
42+ |= [=tako:clay =proses]
43+ ^- wain
44+ :- (crip "commit: {<`@uv`tako>}")
45+ %- zing
46+ %+ join `wain`~['|||']
47+ %+ turn ~(tap in proses)
48+ |= prose
49+ ^- wain
50+ %- to-wain:format
51+ (rap 3 title '\0a\0a' body ~)
52+::
53+:: Parsers
54+::
55+++ parse-commit-hash
56+ ;~ sfix
57+ ;~ pfix (jest 'commit: ')
58+ (cook @uv ;~(pfix (jest '0v') viz:ag))
59+ ==
60+ ::
61+ (just '\0a')
62+ ==
63+::
64+++ parse-title
65+ ;~ sfix
66+ (cook crip (star prn))
67+ (jest '\0a\0a')
68+ ==
69+::
70+++ parse-body
71+ %+ cook of-wain:format
72+ %- star
73+ ;~ less
74+ ;~(pose (jest '|||\0a') (jest '---\0a'))
75+ (cook crip ;~(sfix (star prn) (just '\0a')))
76+ ==
77+::
78+++ parse-prose ;~(plug parse-title parse-body)
79+++ parse-rest-proses (star ;~(pfix (jest '|||\0a') parse-prose))
80+++ parse-proses (cook silt ;~(plug parse-prose parse-rest-proses))
81+++ parse-chapter ;~(plug parse-commit-hash parse-proses)
82+++ parse-story
83+ (cook ~(gas by *story) (star ;~(sfix parse-chapter (jest '---\0a'))))
84+::
85+:: N.B: If conflicting messages are written individually,
86+:: instead of under the same commit, we will overwrite previous entries
87+:: with later ones due to the nature of gas:by.
88+--
base-desk/lib/strand.hoon+1−188
@@ -1,188 +1 @@
1−|%
2−+$ card card:agent:gall
3−+$ input
4− $% [%poke =cage]
5− [%sign =wire =sign-arvo]
6− [%agent =wire =sign:agent:gall]
7− [%watch =path]
8− ==
9−+$ strand-input [=bowl in=(unit input)]
10−+$ tid @tatid
11−+$ bowl
12− $: our=ship
13− src=ship
14− tid=tid
15− mom=(unit tid)
16− wex=boat:gall
17− sup=bitt:gall
18− eny=@uvJ
19− now=@da
20− byk=beak
21− ==
22−::
23−:: cards: cards to send immediately. These will go out even if a
24−:: later stage of the computation fails, so they shouldn't have
25−:: any semantic effect on the rest of the system.
26−:: Alternately, they may record an entry in contracts with
27−:: enough information to undo the effect if the computation
28−:: fails.
29−:: wait: don't move on, stay here. The next sign should come back
30−:: to this same callback.
31−:: skip: didn't expect this input; drop it down to be handled
32−:: elsewhere
33−:: cont: continue computation with new callback.
34−:: fail: abort computation; don't send effects
35−:: done: finish computation; send effects
36−::
37−++ strand-output-raw
38− |* a=mold
39− $~ [~ %done *a]
40− $: cards=(list card)
41− $= next
42− $% [%wait ~]
43− [%skip ~]
44− [%cont self=(strand-form-raw a)]
45− [%fail err=(pair term tang)]
46− [%done value=a]
47− ==
48− ==
49−::
50−++ strand-form-raw
51− |* a=mold
52− $-(strand-input (strand-output-raw a))
53−::
54−:: Abort strand computation with error message
55−::
56−++ strand-fail
57− |= err=(pair term tang)
58− |= strand-input
59− [~ %fail err]
60−::
61−:: Asynchronous transcaction monad.
62−::
63−:: Combo of four monads:
64−:: - Reader on input
65−:: - Writer on card
66−:: - Continuation
67−:: - Exception
68−::
69−++ strand
70− |* a=mold
71− |%
72− ++ output (strand-output-raw a)
73− ::
74− :: Type of an strand computation.
75− ::
76− ++ form (strand-form-raw a)
77− ::
78− :: Monadic pure. Identity computation for bind.
79− ::
80− ++ pure
81− |= arg=a
82− ^- form
83− |= strand-input
84− [~ %done arg]
85− ::
86− :: Monadic bind. Combines two computations, associatively.
87− ::
88− ++ bind
89− |* b=mold
90− |= [m-b=(strand-form-raw b) fun=$-(b form)]
91− ^- form
92− |= input=strand-input
93− =/ b-res=(strand-output-raw b)
94− (m-b input)
95− ^- output
96− :- cards.b-res
97− ?- -.next.b-res
98− %wait [%wait ~]
99− %skip [%skip ~]
100− %cont [%cont ..$(m-b self.next.b-res)]
101− %fail [%fail err.next.b-res]
102− %done [%cont (fun value.next.b-res)]
103− ==
104− ::
105− :: The strand monad must be evaluted in a particular way to maintain
106− :: its monadic character. +take:eval implements this.
107− ::
108− ++ eval
109− |%
110− :: Indelible state of a strand
111− ::
112− +$ eval-form
113− $: =form
114− ==
115− ::
116− :: Convert initial form to eval-form
117− ::
118− ++ from-form
119− |= =form
120− ^- eval-form
121− form
122− ::
123− :: The cases of results of +take
124− ::
125− +$ eval-result
126− $% [%next ~]
127− [%fail err=(pair term tang)]
128− [%done value=a]
129− ==
130− ::
131− ++ validate-mark
132− |= [in=* =mark =bowl]
133− ^- cage
134− =+ .^ =dais:clay %cb
135− /(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[mark]
136− ==
137− =/ res (mule |.((vale.dais in)))
138− ?: ?=(%| -.res)
139− ~|(%spider-mark-fail (mean leaf+"spider: ames vale fail {<mark>}" p.res))
140− [mark p.res]
141− ::
142− :: Take a new sign and run the strand against it
143− ::
144− ++ take
145− :: cards: accumulate throughout recursion the cards to be
146− :: produced now
147− =| cards=(list card)
148− |= [=eval-form =strand-input]
149− ^- [[(list card) =eval-result] _eval-form]
150− =* take-loop $
151− =. in.strand-input
152− ?~ in.strand-input ~
153− =/ in u.in.strand-input
154− ?. ?=(%agent -.in) `in
155− ?. ?=(%fact -.sign.in) `in
156− ::
157− :- ~
158− :+ %agent wire.in
159− [%fact (validate-mark q.q.cage.sign.in p.cage.sign.in bowl.strand-input)]
160− :: run the strand callback
161− ::
162− =/ =output (form.eval-form strand-input)
163− :: add cards to cards
164− ::
165− =. cards
166− %+ welp
167− cards
168− :: XX add tag to wires?
169− cards.output
170− :: case-wise handle next steps
171− ::
172− ?- -.next.output
173− %wait [[cards %next ~] eval-form]
174− %skip [[cards %next ~] eval-form]
175− %fail [[cards %fail err.next.output] eval-form]
176− %done [[cards %done value.next.output] eval-form]
177− %cont
178− :: recurse to run continuation with initialization input
179− ::
180− %_ take-loop
181− form.eval-form self.next.output
182− strand-input [bowl.strand-input ~]
183− ==
184− ==
185− --
186− --
187−--
188−::
1+rand
base-desk/lib/strandio.hoon+171−14
@@ -73,21 +73,23 @@
7373 ^- form:m
7474 |= tin=strand-input:strand
7575 ?+ in.tin `[%skip ~]
76− ~ `[%wait ~]
76+ ~
77+ `[%wait ~]
78+ ::
7779 [~ %poke @ *]
7880 ?. =(mark p.cage.u.in.tin)
7981 `[%skip ~]
8082 `[%done q.cage.u.in.tin]
8183 ==
8284::
83−::
84−::
8585++ take-sign-arvo
8686 =/ m (strand ,[wire sign-arvo])
8787 ^- form:m
8888 |= tin=strand-input:strand
8989 ?+ in.tin `[%skip ~]
90− ~ `[%wait ~]
90+ ~
91+ `[%wait ~]
92+ ::
9193 [~ %sign *]
9294 `[%done [wire sign-arvo]:u.in.tin]
9395 ==
@@ -180,6 +182,53 @@
180182 `[%done ~]
181183 `[%fail %timer-error u.error.sign-arvo.u.in.tin]
182184 ==
185+++ take-whey
186+ |= =wire
187+ =/ m (strand ,[spar:ames fragment-size=@ud num-fragments=@ud])
188+ ^- form:m
189+ |= tin=strand-input:strand
190+ ?+ in.tin `[%skip ~]
191+ ~ `[%wait ~]
192+ ::
193+ [~ %sign * %ames %sage sage=*]
194+ ?. =(wire wire.u.in.tin)
195+ `[%skip ~]
196+ =/ =sage:mess:ames sage.sign-arvo.u.in.tin
197+ :^ ~ %done spar=p.sage
198+ ?~ q.sage
199+ [boq=13 tot=0]
200+ =< [boq tot]
201+ ;;([%whey boq=@ud tot=@ud] q.sage)
202+ ==
203+::
204+++ take-sage
205+ |= =wire
206+ =/ m (strand ,sage:mess:ames)
207+ ^- form:m
208+ |= tin=strand-input:strand
209+ ?+ in.tin `[%skip ~]
210+ ~ `[%wait ~]
211+ ::
212+ [~ %sign * %ames %sage sage=*]
213+ ?. =(wire wire.u.in.tin)
214+ `[%skip ~]
215+ `[%done sage.sign-arvo.u.in.tin]
216+ ==
217+:: XX deprecate in 409k
218+::
219+++ take-near
220+ |= =wire
221+ =/ m (strand ,[spar:ames (unit (unit page))])
222+ ^- form:m
223+ |= tin=strand-input:strand
224+ ?+ in.tin `[%skip ~]
225+ ~ `[%wait ~]
226+ ::
227+ [~ %sign * %ames %near ^ *]
228+ ?. =(wire wire.u.in.tin)
229+ `[%skip ~]
230+ `[%done +>.sign-arvo.u.in.tin]
231+ ==
183232::
184233++ take-poke-ack
185234 |= =wire
@@ -315,6 +364,78 @@
315364 ;< ~ bind:m (send-wait until)
316365 (take-wake `until)
317366::
367+++ mass
368+ =/ m (strand ,(list quac:dill))
369+ ^- form:m
370+ =/ =card:agent:gall [%pass /mass %arvo %d %mass ~]
371+ ;< ~ bind:m (send-raw-card card)
372+ ;< quz=(list quac:dill) bind:m take-meme
373+ (pure:m quz)
374+::
375+++ take-meme
376+ =/ m (strand ,(list quac:dill))
377+ ^- form:m
378+ |= tin=strand-input:strand
379+ ?+ in.tin `[%skip ~]
380+ ~ `[%wait ~]
381+ [~ %sign [%mass ~] %dill %meme *]
382+ `[%done p.sign-arvo.u.in.tin]
383+ ==
384+::
385+++ keen
386+ |= [=wire =spar:ames sec=(unit [@ @])]
387+ =/ m (strand ,~)
388+ ^- form:m
389+ (send-raw-card %pass wire %arvo %a %keen sec spar)
390+::
391+++ chum
392+ |= [=wire =spar:ames]
393+ =/ m (strand ,~)
394+ ^- form:m
395+ (send-raw-card %pass wire %arvo %a %chum spar)
396+::
397+++ keen-shut
398+ |= [=wire =spar:ames]
399+ =/ m (strand ,~)
400+ ^- form:m
401+ (send-raw-card %pass wire %keen & spar)
402+::
403+++ yawn
404+ |= [=wire =spar:ames]
405+ =/ m (strand ,~)
406+ ^- form:m
407+ (send-raw-card %pass wire %arvo %a %yawn spar)
408+::
409+++ whey
410+ |= [=wire boq=@ud =spar:ames]
411+ =/ m (strand ,~)
412+ ^- form:m
413+ :: encrypted using %chum namespace
414+ ::
415+ ;< our=@p bind:m get-our
416+ =. path.spar
417+ [%a %x '1' %$ %whey (scot %ud boq) (scot %p our) path.spar]
418+ (chum wire spar)
419+::
420+++ meta
421+ |= [=wire =spar:ames]
422+ =/ m (strand ,~)
423+ ^- form:m
424+ ?+ path.spar !!
425+ $% [%ames bone=@ %cork ~]
426+ [%ames bone=@ %sent seq=@ ~]
427+ [%flow bone=@ =dire:ames %cork ~]
428+ [?(%ames %flow) bone=@ =dire:ames ?(%sent %loads %naxp %acked) seq=@ ~]
429+ ==
430+ :: encrypted using %chum namespace
431+ ::
432+ ;< our=@p bind:m get-our
433+ %- send-raw-card
434+ :* %pass wire %arvo %a %chum
435+ spar(path [%a %x '1' %$ %meta (scot %p our) path.spar])
436+ ==
437+ ==
438+::
318439++ sleep
319440 |= for=@dr
320441 =/ m (strand ,~)
@@ -433,7 +554,6 @@
433554 %- pure:m
434555 ?~ full-file.client-response ''
435556 q.data.u.full-file.client-response
436−
437557::
438558++ fetch-cord
439559 |= url=tape
@@ -449,7 +569,7 @@
449569 =/ m (strand ,json)
450570 ^- form:m
451571 ;< =cord bind:m (fetch-cord url)
452− =/ json=(unit json) (de-json:html cord)
572+ =/ json=(unit json) (de:json:html cord)
453573 ?~ json
454574 (strand-fail %json-parse-error ~)
455575 (pure:m u.json)
@@ -474,6 +594,18 @@
474594 (pure:m ~)
475595 ?> =(%vase p.r.u.riot)
476596 (pure:m (some !<(vase q.r.u.riot)))
597+::
598+++ build-file-hard
599+ |= [[=ship =desk =case] =spur]
600+ =* arg +<
601+ =/ m (strand ,vase)
602+ ^- form:m
603+ ;< =riot:clay
604+ bind:m
605+ (warp ship desk ~ %sing %a case spur)
606+ ?> ?=(^ riot)
607+ ?> ?=(%vase p.r.u.riot)
608+ (pure:m !<(vase q.r.u.riot))
477609:: +build-mark: build a mark definition to a $dais
478610::
479611++ build-mark
@@ -537,7 +669,7 @@
537669 (take-writ /warp)
538670::
539671++ read-file
540− |= [[=ship =desk =case:clay] =spur]
672+ |= [[=ship =desk =case] =spur]
541673 =* arg +<
542674 =/ m (strand ,cage)
543675 ;< =riot:clay bind:m (warp ship desk ~ %sing %x case spur)
@@ -546,13 +678,14 @@
546678 (pure:m r.u.riot)
547679::
548680++ check-for-file
549− |= [[=ship =desk =case:clay] =spur]
681+ |= [[=ship =desk =case] =spur]
550682 =/ m (strand ,?)
551− ;< =riot:clay bind:m (warp ship desk ~ %sing %x case spur)
552− (pure:m ?=(^ riot))
683+ ;< =riot:clay bind:m (warp ship desk ~ %sing %u case spur)
684+ ?> ?=(^ riot)
685+ (pure:m !<(? q.r.u.riot))
553686::
554687++ list-tree
555− |= [[=ship =desk =case:clay] =spur]
688+ |= [[=ship =desk =case] =spur]
556689 =* arg +<
557690 =/ m (strand ,(list path))
558691 ;< =riot:clay bind:m (warp ship desk ~ %sing %t case spur)
@@ -560,6 +693,14 @@
560693 (strand-fail %list-tree >arg< ~)
561694 (pure:m !<((list path) q.r.u.riot))
562695::
696+++ list-desk
697+ |= [[=ship =desk =case] =spur]
698+ =* arg +<
699+ =/ m (strand arch)
700+ ;< =riot:clay bind:m (warp ship desk ~ %sing %y case spur)
701+ ?~ riot
702+ (strand-fail %list-desk >arg< ~)
703+ (pure:m !<(arch q.r.u.riot))
563704:: Take Clay read result
564705::
565706++ take-writ
@@ -586,6 +727,23 @@
586727 (poke [who %hood] %helm-hi !>(~))
587728 (pure:m ~)
588729::
730+++ eval-hoon
731+ |= [gen=hoon bez=(list beam)]
732+ =/ m (strand ,vase)
733+ ^- form:m
734+ =/ sut=vase !>(..zuse)
735+ |-
736+ ?~ bez
737+ (pure:m (slap sut gen))
738+ ;< vax=vase bind:m (build-file-hard i.bez)
739+ $(bez t.bez, sut (slop vax sut))
740+::
741+++ send-thread
742+ |= [=bear:khan =shed:khan =wire]
743+ =/ m (strand ,~)
744+ ^- form:m
745+ (send-raw-card %pass wire %arvo %k %lard bear shed)
746+::
589747:: Queue on skip, try next on fail %ignore
590748::
591749++ main-loop
@@ -734,7 +892,7 @@
734892 ;< =bowl:spider bind:m get-bowl
735893 =/ tid
736894 (scot %ta (cat 3 (cat 3 'strand_' file) (scot %uv (sham file eny.bowl))))
737− =/ poke-vase !>([`tid.bowl `tid beak file args])
895+ =/ poke-vase !>(`start-args:spider`[`tid.bowl `tid beak file args])
738896 ;< ~ bind:m (poke-our %spider %spider-start poke-vase)
739897 ;< ~ bind:m (sleep ~s0) :: wait for thread to start
740898 (pure:m tid)
@@ -748,10 +906,9 @@
748906 ^- form:m
749907 ;< =bowl:spider bind:m get-bowl
750908 =/ tid (scot %ta (cat 3 'strand_' (scot %uv (sham file eny.bowl))))
751− =/ poke-vase !>([`tid.bowl `tid file args])
909+ =/ poke-vase !>(`start-args:spider`[`tid.bowl `tid byk.bowl file args])
752910 ;< ~ bind:m (watch-our /awaiting/[tid] %spider /thread-result/[tid])
753911 ;< ~ bind:m (poke-our %spider %spider-start poke-vase)
754− ;< ~ bind:m (sleep ~s0) :: wait for thread to start
755912 ;< =cage bind:m (take-fact /awaiting/[tid])
756913 ;< ~ bind:m (take-kick /awaiting/[tid])
757914 ?+ p.cage ~|([%strange-thread-result p.cage file tid] !!)
base-desk/lib/test.hoon+55−2
@@ -13,7 +13,7 @@
1313 %+ weld result
1414 ^- tang
1515 :~ [%palm [": " ~ ~ ~] [leaf+"expected" (sell expected) ~]]
16− [%palm [": " ~ ~ ~] [leaf+"actual" (sell actual) ~]]
16+ [%palm [": " ~ ~ ~] [leaf+"actual " (sell actual) ~]]
1717 ==
1818 ::
1919 =? result !(~(nest ut p.actual) | p.expected)
@@ -38,7 +38,60 @@
3838 =/ b (mule a)
3939 ?- -.b
4040 %| ~
41− %& [leaf+"expected failure - succeeded" ~]
41+ %& ['expected failure - succeeded' ~]
42+ ==
43+:: +expect-success: kicks a trap, expecting success; returns trace on failure
44+::
45+++ expect-success
46+ |= a=(trap)
47+ ^- tang
48+ =/ b (mule a)
49+ ?- -.b
50+ %& ~
51+ %| ['expected success - failed' p.b]
52+ ==
53+::
54+:: +expect-fail-message: kicks a trap, expecting crash, compares the resulting error message
55+++ expect-fail-message
56+ |= [msg=@t a=(trap)]
57+ ^- tang
58+ =/ b (mule a)
59+ ?- -.b
60+ %| |^
61+ =/ =tang (flatten +.b)
62+ ?: ?=(^ (find (trip msg) tang))
63+ ~
64+ ['expected error message - not found' ~]
65+ ++ flatten
66+ |= tang=(list tank)
67+ =| res=tape
68+ |- ^- tape
69+ ?~ tang res
70+ $(tang t.tang, res (weld ~(ram re i.tang) res))
71+ --
72+ %& ['expected failure - succeeded' ~]
73+ ==
74+:: $a-test-chain: a sequence of tests to be run
75+::
76+:: NB: arms shouldn't start with `test-` so that `-test % ~` runs
77+::
78++$ a-test-chain
79+ $_
80+ |?
81+ ?: =(0 0)
82+ [%& p=*tang]
83+ [%| p=[tang=*tang next=^?(..$)]]
84+:: +run-chain: run a sequence of tests, stopping at first failure
85+::
86+++ run-chain
87+ |= seq=a-test-chain
88+ ^- tang
89+ =/ res $:seq
90+ ?- -.res
91+ %& p.res
92+ %| ?. =(~ tang.p.res)
93+ tang.p.res
94+ $(seq next.p.res)
4295 ==
4396:: +category: prepends a name to an error result; passes successes unchanged
4497::
base-desk/lib/verb.hoon+88−11
@@ -1,6 +1,6 @@
11:: Print what your agent is doing.
22::
3−/- verb
3+/- *verb
44::
55|= [loud=? =agent:gall]
66=| bowl-print=_|
@@ -14,7 +14,10 @@
1414 ^- (quip card:agent:gall agent:gall)
1515 %- (print bowl |.("{<dap.bowl>}: on-init"))
1616 =^ cards agent on-init:ag
17− [[(emit-event %on-init ~) cards] this]
17+ :_ this
18+ :_ :_ cards
19+ (emit-event %on-init ~)
20+ (emit-event-plus bowl [%on-init ~] cards)
1821::
1922++ on-save
2023 ^- vase
@@ -26,7 +29,10 @@
2629 ^- (quip card:agent:gall agent:gall)
2730 %- (print bowl |.("{<dap.bowl>}: on-load"))
2831 =^ cards agent (on-load:ag old-state)
29− [[(emit-event %on-load ~) cards] this]
32+ :_ this
33+ :_ :_ cards
34+ (emit-event %on-load ~)
35+ (emit-event-plus bowl [%on-load ~] cards)
3036::
3137++ on-poke
3238 |= [=mark =vase]
@@ -38,17 +44,23 @@
3844 %bowl `this(bowl-print !bowl-print)
3945 ==
4046 =^ cards agent (on-poke:ag mark vase)
41− [[(emit-event %on-poke mark) cards] this]
47+ :_ this
48+ :_ :_ cards
49+ (emit-event %on-poke mark)
50+ (emit-event-plus bowl [%on-poke mark (mug q.vase)] cards)
4251::
4352++ on-watch
4453 |= =path
4554 ^- (quip card:agent:gall agent:gall)
4655 %- (print bowl |.("{<dap.bowl>}: on-watch on path {<path>}"))
4756 =^ cards agent
48− ?: ?=([%verb %events ~] path)
57+ ?: ?=([%verb ?(%events %events-plus) ~] path)
4958 [~ agent]
5059 (on-watch:ag path)
51− [[(emit-event %on-watch path) cards] this]
60+ :_ this
61+ :_ :_ cards
62+ (emit-event %on-watch path)
63+ (emit-event-plus bowl [%on-watch path] cards)
5264::
5365++ on-leave
5466 |= =path
@@ -57,7 +69,10 @@
5769 ?: ?=([%verb %event ~] path)
5870 [~ this]
5971 =^ cards agent (on-leave:ag path)
60− [[(emit-event %on-leave path) cards] this]
72+ :_ this
73+ :_ :_ cards
74+ (emit-event %on-leave path)
75+ (emit-event-plus bowl [%on-leave path] cards)
6176::
6277++ on-peek
6378 |= =path
@@ -70,7 +85,17 @@
7085 ^- (quip card:agent:gall agent:gall)
7186 %- (print bowl |.("{<dap.bowl>}: on-agent on wire {<wire>}, {<-.sign>}"))
7287 =^ cards agent (on-agent:ag wire sign)
73− [[(emit-event %on-agent wire -.sign) cards] this]
88+ :_ this
89+ :_ :_ cards
90+ (emit-event %on-agent wire -.sign)
91+ =; =^sign
92+ (emit-event-plus bowl [%on-agent wire sign] cards)
93+ ?- -.sign
94+ %poke-ack [%poke-ack ?=(~ p.sign)]
95+ %watch-ack [%watch-ack ?=(~ p.sign)]
96+ %kick [%kick ~]
97+ %fact [%fact p.cage.sign (mug q.q.cage.sign)]
98+ ==
7499::
75100++ on-arvo
76101 |= [=wire =sign-arvo]
@@ -78,14 +103,20 @@
78103 %- %+ print bowl |.
79104 "{<dap.bowl>}: on-arvo on wire {<wire>}, {<[- +<]:sign-arvo>}"
80105 =^ cards agent (on-arvo:ag wire sign-arvo)
81− [[(emit-event %on-arvo wire [- +<]:sign-arvo) cards] this]
106+ :_ this
107+ :_ :_ cards
108+ (emit-event %on-arvo wire [- +<]:sign-arvo)
109+ (emit-event-plus bowl [%on-arvo wire [- +<]:sign-arvo] cards)
82110::
83111++ on-fail
84112 |= [=term =tang]
85113 ^- (quip card:agent:gall agent:gall)
86114 %- (print bowl |.("{<dap.bowl>}: on-fail with term {<term>}"))
87115 =^ cards agent (on-fail:ag term tang)
88− [[(emit-event %on-fail term) cards] this]
116+ :_ this
117+ :_ :_ cards
118+ (emit-event %on-fail term)
119+ (emit-event-plus bowl [%on-fail term] cards)
89120--
90121::
91122++ print
@@ -99,7 +130,53 @@
99130 same
100131::
101132++ emit-event
102− |= =event:verb
133+ |= =event
103134 ^- card:agent:gall
104135 [%give %fact ~[/verb/events] %verb-event !>(event)]
136+::
137+++ emit-event-plus
138+ |= [=bowl:gall =cause cards=(list card:agent:gall)]
139+ ^- card:agent:gall
140+ =; event=event-plus
141+ [%give %fact ~[/verb/events-plus] %verb-event-plus !>(event)]
142+ =- [act.bowl now.bowl src.bowl sap.bowl cause -]
143+ %+ turn cards
144+ |= =card:agent:gall
145+ ^- effect
146+ ::TODO for %fact, %kick, could calculate how many ships affected
147+ ?- card
148+ [%pass * %agent * ?(%poke %poke-as) *]
149+ =, q.card
150+ =/ =cage ?-(-.task.q.card %poke cage.task, %poke-as [mark.task q.cage.task])
151+ [%poke p.card [ship name] p.cage `@`(mug q.q.cage)]
152+ ::
153+ [%pass * %agent * ?(%watch %watch-as) *]
154+ =, q.card
155+ =/ =path ?-(-.task.q.card %watch path.task, %watch-as path.task)
156+ [%watch p.card [ship name] path]
157+ ::
158+ [%pass * %agent * %leave *]
159+ =, q.card
160+ [%leave p.card [ship name]]
161+ ::
162+ [%give %fact *]
163+ =, p.card
164+ [%fact paths p.cage (mug q.q.cage)]
165+ ::
166+ [%give %kick *]
167+ [%kick paths.p.card]
168+ ::
169+ [%give ?(%poke-ack %watch-ack) *]
170+ ~| %explicit-ack
171+ !! :: shouldn't be given explicitly
172+ ::
173+ [%pass * %arvo *]
174+ [%arvo p.card -.q.card +<.q.card]
175+ ::
176+ [%pass *]
177+ [%arvo p.card %$ -.q.card]
178+ ::
179+ [%slip *]
180+ $(card [%pass //slip p.card])
181+ ==
105182--
base-desk/mar/belt.hoon+3−12
@@ -1,5 +1,7 @@
11:: belt: runtime belt structure
22::
3+/+ dill
4+::
35|_ =belt:dill
46++ grad %noun
57:: +grab: convert from
@@ -7,18 +9,7 @@
79++ grab
810 |%
911 ++ noun belt:dill
10− ++ json
11− ^- $-(^json belt:dill)
12− =, dejs:format
13− %- of
14− :~ aro+(su (perk %d %l %r %u ~))
15− bac+ul
16− ctl+(cu taft so)
17− del+ul
18− met+(cu taft so)
19− ret+ul
20− txt+(ar (cu taft so))
21− ==
12+ ++ json belt:dejs:dill
2213 --
2314:: +grow: convert to
2415::
base-desk/mar/blit.hoon+3−44
@@ -1,5 +1,7 @@
11:: blit: runtime blit structure
22::
3+/+ dill
4+::
35|_ =blit:dill
46++ grad %noun
57:: +grab: convert from
@@ -13,49 +15,6 @@
1315++ grow
1416 |%
1517 ++ noun blit
16− ++ json
17− ^- ^json
18− =, enjs:format
19− %+ frond -.blit
20− ?- -.blit
21− %bel b+&
22− %clr b+&
23− %hop (numb p.blit)
24− %lin a+(turn p.blit |=(c=@c s+(tuft c)))
25− %mor b+&
26− %url s+p.blit
27− ::
28− %sag
29− %- pairs
30− :~ 'path'^(path p.blit)
31− 'file'^s+(en:base64:mimes:html (as-octs:mimes:html (jam q.blit)))
32− ==
33− ::
34− %sav
35− %- pairs
36− :~ 'path'^(path p.blit)
37− 'file'^s+(en:base64:mimes:html (as-octs:mimes:html q.blit))
38− ==
39− ::
40− %klr
41− :- %a
42− %+ turn p.blit
43− |= [=stye text=(list @c)]
44− %- pairs
45− :~ 'text'^a+(turn text |=(c=@c s+(tuft c)))
46− ::
47− :- 'stye'
48− %- pairs
49− |^ :~ 'back'^(color p.q.stye)
50− 'fore'^(color q.q.stye)
51− 'deco'^a+(turn ~(tap in p.stye) |=(d=deco ?~(d ~ s+d)))
52− ==
53− ++ color
54− |= =tint
55− ?@ tint ?~(tint ~ s+tint)
56− s+(crip ((x-co:co 6) (rep 3 ~[b g r]:tint)))
57− --
58− ==
59− ==
18+ ++ json (blit:enjs:dill blit)
6019 --
6120--
base-desk/mar/css.hoonnew file+25
@@ -0,0 +1,25 @@
1+::
2+:::: /hoon/css/mar
3+ ::
4+/? 310
5+=, eyre
6+=, mimes:html
7+|_ mud=@t
8+++ grow :: convert to
9+ |%
10+ ++ mime [/text/css (as-octs mud)] :: convert to %mime
11+ ++ hymn :: convert to %hymn
12+ |^ html
13+ ++ style ;style
14+ ;- (trip mud)
15+ ==
16+ ++ html ;html:(head:"{style}" body)
17+ --
18+ --
19+++ grab
20+ |% :: convert from
21+ ++ mime |=([p=mite q=octs] (@t q.q))
22+ ++ noun @t :: clam from %noun
23+ --
24+++ grad %mime
25+--
base-desk/mar/hoon.hoon+285−31
@@ -1,41 +1,295 @@
1−:::: /hoon/hoon/mar
2− ::
3−/? 310
4−::
5−=, eyre
61|_ own=@t
72::
83++ grow :: convert to
94 |%
105 ++ mime `^mime`[/text/x-hoon (as-octs:mimes:html own)] :: convert to %mime
11− ++ elem :: convert to %html
12− ;div:pre(urb_codemirror "", mode "hoon"):"{(trip own)}"
13− :: =+ gen-id="src-{<`@ui`(mug own)>}"
14− :: ;div
15− :: ;textarea(id "{gen-id}"):"{(trip own)}"
16− :: ;script:"""
17− :: CodeMirror.fromTextArea(
18− :: window[{<gen-id>}],
19− :: \{lineNumbers:true, readOnly:true}
20− :: )
21− :: """
22− :: ==
236 ++ hymn
24− :: ;html:(head:title:"Source" "+{elem}")
25− ;html
26− ;head
27− ;title:"Source"
28− ;script@"//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.js";
29− ;script@"/lib/syntax/hoon.js";
30− ;link(rel "stylesheet", href "//cdnjs.cloudflare.com/ajax/libs/".
31− "codemirror/4.3.0/codemirror.min.css");
32− ;link/"/lib/syntax/codemirror.css"(rel "stylesheet");
33− ==
34− ;body
35− ;textarea#src:"{(trip own)}"
36− ;script:'CodeMirror.fromTextArea(src, {lineNumbers:true, readOnly:true})'
7+ ^- manx
8+ =/ to-wall
9+ |= =tape
10+ ^- wall
11+ %+ roll (flop tape)
12+ |= [char=@tD =wall]
13+ ?~ wall
14+ [[char ~] ~]
15+ ?: =('\0a' char)
16+ [~ wall]
17+ [[char i.wall] t.wall]
18+ ::
19+ =/ src=tape (trip own)
20+ =/ count=@ud (lent (to-wall src))
21+ =; [style=tape script=tape]
22+ ;html
23+ ;head
24+ ;title: source
25+ ;meta(charset "utf-8");
26+ ;meta(name "viewport", content "width=device-width, initial-scale=1");
27+ ;style: {style}
28+ ==
29+ ;body
30+ ;div.viewer
31+ :: ;div.viewer-bar
32+ :: ;span.viewer-name: {(scow %ud count)} lines
33+ :: ;button.copy-link(id "copy-link", hidden ""): copy link
34+ :: ==
35+ ;div.code
36+ ;pre.gutter(id "gutter");
37+ ;div.code-body
38+ ;div(id "hl");
39+ ;pre.code-pre(id "code"): {src}
40+ ==
41+ ==
42+ ==
43+ ;script: {script}
44+ ==
3745 ==
38− ==
46+ ::
47+ :-
48+ ^~ ^= style
49+ ^- tape
50+ %- trip
51+ '''
52+ :root {
53+ --bg: #fbfbf9;
54+ --panel: #ffffff;
55+ --gutter-bg: #f3f3ef;
56+ --line: #e4e4dd;
57+ --fg: #2b2b2b;
58+ --fg-dim: #9a9a90;
59+ --sel: #fff7d6;
60+ --sel-edge: #f1e4a8;
61+ --accent: #4a6da7;
62+ --lh: 20px;
63+ --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
64+ "Liberation Mono", "Courier New", monospace;
65+ }
66+ * { box-sizing: border-box; }
67+ html, body {
68+ margin: 0;
69+ height: 100%;
70+ background: var(--bg);
71+ color: var(--fg);
72+ font-family: var(--mono);
73+ -webkit-font-smoothing: antialiased;
74+ }
75+ .viewer {
76+ height: 100vh;
77+ display: flex;
78+ flex-direction: column;
79+ padding: 16px;
80+ gap: 12px;
81+ }
82+ .viewer-bar {
83+ flex: 0 0 auto;
84+ display: flex;
85+ align-items: center;
86+ gap: 12px;
87+ font-size: 13px;
88+ color: var(--fg-dim);
89+ }
90+ .viewer-name {
91+ flex: 1 1 auto;
92+ min-width: 0;
93+ overflow: hidden;
94+ text-overflow: ellipsis;
95+ white-space: nowrap;
96+ color: var(--fg);
97+ }
98+ .copy-link {
99+ flex: 0 0 auto;
100+ padding: 4px 12px;
101+ border: 1px solid var(--line);
102+ border-radius: 6px;
103+ background: var(--panel);
104+ color: var(--fg-dim);
105+ font: inherit;
106+ font-size: 12px;
107+ cursor: pointer;
108+ transition: color .12s, border-color .12s;
109+ }
110+ .copy-link:hover { color: var(--accent); border-color: var(--accent); }
111+ .copy-link[hidden] { display: none; }
112+ .code {
113+ flex: 1 1 auto;
114+ min-height: 0;
115+ display: flex;
116+ align-items: flex-start;
117+ overflow: auto;
118+ background: var(--panel);
119+ border: 1px solid var(--line);
120+ border-radius: 8px;
121+ }
122+ .code-body {
123+ position: relative;
124+ flex: 1 1 auto;
125+ min-width: 0;
126+ width: max-content;
127+ }
128+ #gutter, #code {
129+ margin: 0;
130+ padding: 14px 0;
131+ font-family: var(--mono);
132+ font-size: 13px;
133+ line-height: var(--lh);
134+ white-space: pre;
135+ tab-size: 2;
136+ }
137+ #gutter {
138+ position: sticky;
139+ left: 0;
140+ z-index: 2;
141+ flex: 0 0 auto;
142+ padding-left: 16px;
143+ padding-right: 12px;
144+ text-align: right;
145+ color: var(--fg-dim);
146+ background: var(--gutter-bg);
147+ border-right: 1px solid var(--line);
148+ user-select: none;
149+ -webkit-user-select: none;
150+ cursor: pointer;
151+ }
152+ #code {
153+ display: block;
154+ padding-left: 14px;
155+ padding-right: 18px;
156+ color: var(--fg);
157+ }
158+ #hl {
159+ position: absolute;
160+ left: 0;
161+ right: 0;
162+ z-index: 0; /* under the text */
163+ display: none;
164+ background: var(--sel);
165+ box-shadow: inset 2px 0 0 var(--sel-edge);
166+ pointer-events: none;
167+ }
168+ #code { position: relative; z-index: 1; } /* text above the bar */
169+ :focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
170+ '''
171+ ^~ ^= code
172+ ^- tape
173+ %- trip
174+ '''
175+ (function () {
176+ "use strict";
177+ const panel = document.querySelector(".code"); // the scroll container
178+ const code = document.getElementById("code");
179+ const gutter = document.getElementById("gutter");
180+ const hl = document.getElementById("hl");
181+ if (!panel || !code || !gutter || !hl) return;
182+ const text = code.textContent;
183+ let lineCount = text.length ? text.split("\n").length : 1;
184+ if (text.endsWith("\n")) lineCount -= 1;
185+ if (lineCount < 1) lineCount = 1;
186+ (function fillGutter() {
187+ let s = "";
188+ for (let i = 1; i <= lineCount; i++) s += i + "\n";
189+ gutter.textContent = s;
190+ })();
191+ let lineH = 0;
192+ let codeTop = 0; // code's content-box top padding, the y-origin of line 1
193+ function measure() {
194+ const cs = getComputedStyle(code);
195+ const lh = parseFloat(cs.lineHeight);
196+ lineH = isNaN(lh) ? parseFloat(cs.fontSize) * 1.55 : lh;
197+ codeTop = parseFloat(cs.paddingTop) || 0;
198+ positionHighlight(); // keep the bar correct after a re-measure
199+ }
200+ let anchor = null;
201+ let selLo = 0;
202+ let selHi = 0;
203+ function positionHighlight() {
204+ if (!selLo) { hl.style.display = "none"; return; }
205+ hl.style.display = "block";
206+ hl.style.top = (codeTop + (selLo - 1) * lineH) + "px";
207+ hl.style.height = ((selHi - selLo + 1) * lineH) + "px";
208+ }
209+ function applySel(lo, hi) {
210+ selLo = lo;
211+ selHi = hi;
212+ positionHighlight();
213+ }
214+ function deselect() {
215+ selLo = selHi = 0;
216+ anchor = null;
217+ positionHighlight();
218+ history.replaceState(null, "", location.pathname + location.search);
219+ }
220+ function parseHash(hash) {
221+ const m = /^#L(\d+)(?:-L(\d+))?$/.exec(hash || "");
222+ if (!m) return null;
223+ let lo = parseInt(m[1], 10);
224+ let hi = m[2] ? parseInt(m[2], 10) : lo;
225+ if (hi < lo) { const t = lo; lo = hi; hi = t; }
226+ lo = Math.max(1, Math.min(lo, lineCount));
227+ hi = Math.max(1, Math.min(hi, lineCount));
228+ return [lo, hi];
229+ }
230+ function setHash(lo, hi) {
231+ const frag = lo === hi ? "L" + lo : "L" + lo + "-L" + hi;
232+ history.replaceState(null, "", "#" + frag);
233+ }
234+ function scrollToLine(n) {
235+ const y = codeTop + (n - 1) * lineH;
236+ if (y < panel.scrollTop || y > panel.scrollTop + panel.clientHeight) {
237+ panel.scrollTop = Math.max(0, y - panel.clientHeight / 2);
238+ }
239+ }
240+ function selectFromHash(scroll) {
241+ const r = parseHash(location.hash);
242+ if (!r) return false;
243+ anchor = r[0];
244+ applySel(r[0], r[1]);
245+ if (scroll) scrollToLine(r[0]);
246+ return true;
247+ }
248+ function lineFromEvent(e) {
249+ // y within the code content: pointer relative to the code pre's rendered
250+ // top, which already accounts for scroll since getBoundingClientRect is
251+ // viewport-relative and the pre moves as the panel scrolls.
252+ const rect = code.getBoundingClientRect();
253+ const y = e.clientY - rect.top - codeTop;
254+ let n = Math.floor(y / lineH) + 1;
255+ if (n < 1) n = 1;
256+ if (n > lineCount) n = lineCount;
257+ return n;
258+ }
259+ function onClick(e) {
260+ const inGutter = e.target === gutter;
261+ if (!inGutter && !e.shiftKey) return; // normal text interaction in code
262+ const n = lineFromEvent(e);
263+ if (!e.shiftKey && selLo === n && selHi === n) {
264+ deselect();
265+ return;
266+ }
267+ if (e.shiftKey && anchor !== null) {
268+ applySel(Math.min(anchor, n), Math.max(anchor, n));
269+ setHash(selLo, selHi);
270+ } else {
271+ anchor = n;
272+ applySel(n, n);
273+ setHash(n, n);
274+ }
275+ }
276+ gutter.addEventListener("click", onClick);
277+ code.addEventListener("click", onClick);
278+ document.addEventListener("keydown", function (e) {
279+ if (e.key === "Escape") deselect();
280+ });
281+ window.addEventListener("hashchange", function () {
282+ if (!selectFromHash(true)) deselect();
283+ });
284+ let rz = null;
285+ window.addEventListener("resize", function () {
286+ clearTimeout(rz);
287+ rz = setTimeout(measure, 100);
288+ });
289+ measure();
290+ selectFromHash(true);
291+ })();
292+ '''
39293 ++ txt
40294 (to-wain:format own)
41295 --
base-desk/mar/htm.hoon+2−11
@@ -2,14 +2,5 @@
22:::: /hoon/htm/mar
33 ::
44/? 310
5−|_ own=manx
6−::
7−++ grad %noun
8−++ grow :: convert to
9− |%
10− ++ noun own
11− ++ hymn own
12− --
13−++ grab |% :: convert from
14− ++ noun manx :: clam from %noun
15−-- --
5+/= htm /mar/html
6+htm
base-desk/mar/httr.hoon+1−2
@@ -5,12 +5,11 @@
55::
66=, eyre
77=, format
8−=, html
98|_ hit=httr
109++ grad %noun
1110++ grow |% ++ wall (turn wain trip)
1211 ++ wain (to-wain cord)
13− ++ json (need (de-json cord))
12+ ++ json (need (de:json:html cord))
1413 ++ cord q:octs
1514 ++ noun hit
1615 ++ octs
base-desk/mar/js.hoon+7−4
@@ -8,10 +8,13 @@
88++ grow
99 |%
1010 ++ mime [/application/javascript (as-octs:mimes:html (@t mud))]
11− ++ elem ;script
12− ;- (trip (@t mud))
13− ==
14− ++ hymn ;html:(head:"+{elem}" body)
11+ ++ hymn :: convert to %hymn
12+ |^ html
13+ ++ script ;script
14+ ;- (trip (@t mud))
15+ ==
16+ ++ html ;html:(head:"{script}" body)
17+ --
1518 --
1619++ grab
1720 |% :: convert from
base-desk/mar/json.hoon+4−4
@@ -8,17 +8,17 @@
88=, eyre
99=, format
1010=, html
11−|_ jon=json
11+|_ jon=^json
1212::
1313++ grow :: convert to
1414 |%
1515 ++ mime [/application/json (as-octs:mimes -:txt)] :: convert to %mime
16− ++ txt [(crip (en-json jon))]~
16+ ++ txt [(en:json jon)]~
1717 --
1818++ grab
1919 |% :: convert from
20− ++ mime |=([p=mite q=octs] (fall (rush (@t q.q) apex:de-json) *json))
21− ++ noun json :: clam from %noun
20+ ++ mime |=([p=mite q=octs] (fall (de:json (@t q.q)) *^json))
21+ ++ noun ^json :: clam from %noun
2222 ++ numb numb:enjs
2323 ++ time time:enjs
2424 --
base-desk/mar/json/rpc/response.hoon+1−2
@@ -16,11 +16,10 @@
1616 ^- response
1717 ~| hit
1818 ?: ?=(%2 (div p.hit 100))
19− =, html
2019 %- json
2120 ?~ r.hit
2221 a+~
23− (need (de-json q:u.r.hit))
22+ (need (de:json:html q:u.r.hit))
2423 fail+hit
2524 ++ json :: from json
2625 =, dejs-soft:format
base-desk/mar/kelvin.hoon+16−6
@@ -1,18 +1,28 @@
1−=/ weft ,[lal=@tas num=@ud] :: TODO remove after merge
2−|_ kel=weft
1+|_ kal=waft:clay
32++ grow
43 |%
54 ++ mime `^mime`[/text/x-kelvin (as-octs:mimes:html hoon)]
6− ++ noun kel
7− ++ hoon (crip "{<[lal num]:kel>}\0a")
5+ ++ noun kal
6+ ++ hoon
7+ %+ rap 3
8+ %+ turn
9+ %+ sort
10+ ~(tap in (waft-to-wefts:clay kal))
11+ |= [a=weft b=weft]
12+ ?: =(lal.a lal.b)
13+ (gte num.a num.b)
14+ (gte lal.a lal.b)
15+ |= =weft
16+ (rap 3 '[%' (scot %tas lal.weft) ' ' (scot %ud num.weft) ']\0a' ~)
17+ ::
818 ++ txt (to-wain:format hoon)
919 --
1020++ grab
1121 |%
12− ++ noun weft
22+ ++ noun waft:clay
1323 ++ mime
1424 |= [=mite len=@ud tex=@]
15− !<(weft (slap !>(~) (ream tex)))
25+ (cord-to-waft:clay tex)
1626 --
1727++ grad %noun
1828--
base-desk/mar/noun.hoon+3
@@ -8,6 +8,9 @@
88++ grab |%
99 ++ noun *
1010 --
11+++ grow |%
12+ ++ mime [/application/x-urb-jam (as-octs:mimes:html (jam non))]
13+ --
1114++ grad
1215 |%
1316 ++ form %noun
base-desk/mar/sole/action.hoon+3−1
@@ -20,7 +20,9 @@
2020 |= jon=^json ^- sole-action
2121 %- need %. jon
2222 => [dejs-soft:format ..sole-action]
23− |^ (ot id+so dat+(fo %ret (of det+change tab+ni ~)) ~)
23+ |^ (ot id+id dat+(fo %ret (of det+change tab+ni ~)) ~)
24+ ++ id
25+ (ot who+(su ;~(pfix sig fed:ag)) ses+so ~)
2426 ++ fo
2527 |* [a=term b=fist]
2628 |=(c=json ?.(=([%s a] c) (b c) (some [a ~])))
base-desk/mar/story-diff.hoonnew file+16
@@ -0,0 +1,16 @@
1+::
2+::::
3+ ::
4+/- *story
5+|_ =story-diff
6+::
7+++ grad %noun
8+++ grow
9+ |%
10+ ++ noun story-diff
11+ --
12+++ grab :: convert from
13+ |%
14+ ++ noun ^story-diff :: make from %noun
15+ --
16+--
base-desk/mar/story.hoonnew file+65
@@ -0,0 +1,65 @@
1+/- *story
2+/+ *story
3+|_ tale=story
4+++ grad
5+ |%
6+ ++ form %story-diff
7+ ++ diff
8+ |= tory=story
9+ ^- story-diff
10+ :: Given new story (tory), old story (tale), compute the diff
11+ :: additions = new - old
12+ :: deletions = old - new
13+ [(dif-ju tory tale) (dif-ju tale tory)]
14+ ++ pact
15+ |= dif=story-diff
16+ :: Compute the new story after applying dif to tale.
17+ ::
18+ ^- story
19+ =. tale (uni-ju tale additions.dif)
20+ =. tale (dif-ju tale deletions.dif)
21+ tale
22+ ++ join
23+ |= [ali=story-diff bob=story-diff]
24+ ^- (unit story-diff)
25+ =/ joined-additions (uni-ju additions.ali additions.bob)
26+ =/ joined-deletions (uni-ju deletions.ali deletions.bob)
27+ ::
28+ :: In a true join, we'd do a set intersection on the keys.
29+ :: If they're not equal, we have a conflict.
30+ :: In this case, we'd produce null and kick the flow to +mash
31+ ::
32+ %- some
33+ [joined-additions joined-deletions]
34+ ++ mash
35+ :: called by meld, force merge, annotating conflicts
36+ |= $: [als=ship ald=desk ali=story-diff]
37+ [bos=ship bod=desk bob=story-diff]
38+ ==
39+ ^- story-diff
40+ (need (join ali bob)) :: XX temporary, only because join doesn't fail
41+ --
42+::
43+++ grow :: convert to
44+ |% ::
45+ ++ mime :: to %mime
46+ [/text/x-urb-story (as-octs:mimes:html (of-wain:format txt))]
47+ ++ txt
48+ ^- wain
49+ %- zing
50+ %+ join `wain`~['---']
51+ %+ murn ~(tap by tale)
52+ |= [=tako:clay =proses]
53+ ^- (unit wain)
54+ ?~ proses ~
55+ (some (chapter-to-text tako proses))
56+ --
57+++ grab
58+ |% :: convert from
59+ ++ noun story :: clam from %noun
60+ ++ mime :: retrieve from %mime
61+ |= [p=mite q=octs]
62+ =/ story-text `@t`q.q
63+ `story`(rash story-text parse-story)
64+ --
65+--
base-desk/mar/tang.hoon+5−5
@@ -16,15 +16,15 @@
1616 %& a+p.result
1717 %| a+[a+[%s '[[output rendering error]]']~]~
1818 ==
19− ::
20− ++ elem
21− =- ;pre:code:"{(of-wall -)}"
22− ^- wall %- zing ^- (list wall)
23− (turn (flop tan) |=(a=tank (wash 0^160 a)))
19+ ++ txt
20+ ^- wain
21+ %+ turn (flop tan)
22+ |=(=tank (crip ~(ram re tank)))
2423 --
2524++ grab :: convert from
2625 |%
2726 ++ noun (list ^tank) :: clam from %noun
2827 ++ tank |=(a=^tank [a]~)
28+ ++ txt |=(=wain (flop (turn wain tank)))
2929 --
3030--
base-desk/mar/thread-done.hoonnew file+11
@@ -0,0 +1,11 @@
1+|_ res=*
2+++ grab
3+ |%
4+ ++ noun *
5+ --
6+++ grow
7+ |%
8+ ++ noun res
9+ --
10+++ grad %noun
11+--
base-desk/mar/thread-fail.hoonnew file+11
@@ -0,0 +1,11 @@
1+|_ err=[term tang]
2+++ grab
3+ |%
4+ ++ noun (pair term tang)
5+ --
6+++ grow
7+ |%
8+ ++ noun err
9+ --
10+++ grad %noun
11+--
base-desk/mar/txt.hoon−1
@@ -18,7 +18,6 @@
1818 => v=.
1919 |%
2020 ++ mime => v [/text/plain (as-octs (of-wain txt))]
21− ++ elem => v ;pre: {(trip (of-wain txt))}
2221 --
2322++ grad
2423 |%
base-desk/mar/udon.hoon−5
@@ -9,10 +9,6 @@
99 ++ mime [/text/x-unmark (as-octs:mimes:html mud)]
1010 ++ txt
1111 (to-wain:format mud)
12− ++ elem
13− ^- manx
14− =, cram
15− elm:(static (ream mud))
1612 ++ front :: XX performance, types
1713 ^- (map term knot)
1814 %- ~(run by inf:(static:cram (ream mud)))
@@ -28,5 +24,4 @@
2824 ++ txt of-wain:format
2925 --
3026++ grad %txt
31−++ garb /down
3227--
base-desk/mar/umd.hoon−4
@@ -9,10 +9,6 @@
99 ++ mime [/text/x-unmark (as-octs:mimes:html mud)]
1010 ++ txt
1111 (to-wain:format mud)
12− ++ elem
13− ^- manx
14− =, cram
15− elm:(static (ream mud))
1612 ++ front :: XX performance, types
1713 ^- (map term knot)
1814 %- ~(run by inf:(static:cram (ream mud)))
base-desk/mar/urb.hoon+1−1
@@ -1,5 +1,5 @@
11::
2−:::: /hoon/elem/urb/mar
2+:::: /hoon/urb/mar
33 ::
44/? 310
55=, mimes:html
base-desk/sources.txt+2−3
@@ -1,4 +1,3 @@
11urbit-src/pkg/base-dev
2−urbit-src/pkg/garden-dev
3−urbit-src/pkg/arvo/lib/naive
4−urbit-src/pkg/arvo/lib/tiny
2+urbit-src/pkg/landscape
3+urbit-src/pkg/arvo
base-desk/sur/aquarium.hoon+18−5
@@ -10,8 +10,6 @@
1010:: Short names are simply the first letter of each word plus `s` if
1111:: it's a list.
1212::
13−/+ pill
14−=, pill-lib=pill
1513|%
1614+$ az-log [topics=(lest @) data=@t]
1715+$ az-state
@@ -24,14 +22,23 @@
2422 aqua-event
2523 ==
2624::
27−+$ unix-event unix-event:pill-lib
28−+$ pill pill:pill-lib
25++$ unix-event ::NOTE like unix-event:pill-lib but for all tasks
26+ %+ pair wire
27+ $% [%wack p=@]
28+ [%what p=(list (pair path (cask)))]
29+ [%whom p=ship]
30+ [%boot ? $%($>(%fake task:jael) $>(%dawn task:jael))]
31+ [%wyrd p=vere]
32+ [%verb p=(unit ?)]
33+ task-arvo
34+ ==
2935::
3036+$ aqua-event
31− $% [%init-ship who=ship fake=?]
37+ $% [%init-ship who=ship fake=? feed=(unit feed:jael)]
3238 [%pause-events who=ship]
3339 [%snap-ships lab=term hers=(list ship)]
3440 [%restore-snap lab=term]
41+ [%read [from=[=ship life=@ubC] =path] for=[=lane:ames life=@ubC] num=@ud]
3542 [%event who=ship ue=unix-event]
3643 ==
3744::
@@ -64,6 +71,9 @@
6471 %+ pair wire
6572 $% [%blit p=(list blit:dill)]
6673 [%send p=lane:ames q=@]
74+ [%push p=(list lane:pact:ames) q=@]
75+ [%saxo sponsors=(list ship)]
76+ [%nail =ship lanes=(list lane:ames)]
6777 [%doze p=(unit @da)]
6878 [%thus p=@ud q=(unit hiss:eyre)]
6979 [%ergo p=@tas q=mode:clay]
@@ -72,5 +82,8 @@
7282 [%kill ~]
7383 [%init ~]
7484 [%request id=@ud request=request:http]
85+ [%turf p=(list turf)]
86+ [%unto =unto:gall] :: internal gifts to host ships
87+ :: (%facts are transformed to %raw-facts)
7588 ==
7689--
base-desk/sur/bitcoin.hoon+1−1
@@ -4,7 +4,7 @@
44:: chyg: whether account is (non-)change. 0 or 1
55:: bytc: "btc-byts" with dat cast to @ux
66|%
7−+$ network ?(%main %testnet)
7++$ network ?(%main %testnet %regtest)
88+$ hexb [wid=@ dat=@ux] :: hex byts
99+$ bits [wid=@ dat=@ub]
1010+$ xpub @ta
base-desk/sur/hood.hoon+283−197
@@ -1,152 +1,312 @@
1+/% kelvin %kelvin
12=, clay
23=* dude dude:gall
34|%
4−:: $snap: kiln snapshot
5++$ pike
6+ $: sync=(unit [=ship =desk])
7+ hash=@uv
8+ =zest
9+ wic=(set weft)
10+ ==
511::
6−+$ snap (map desk arak)
7−:: $diff: subscription update
12++$ pikes (map desk pike)
13+:: $jump: changes to update source change requests
814::
9−+$ diff
10− $% [%block =desk =arak =weft blockers=(set desk)]
11− [%reset =desk =arak]
12− [%commit =desk =arak]
13− [%merge-sunk =desk =arak =tang]
14− [%merge-fail =desk =arak =tang]
15− [%suspend =desk =arak]
16− [%revive =desk =arak]
15++$ jump
16+ $% [%all all=(map dock dock)] :: pending requests
17+ [%add old=dock new=dock] :: new request
18+ [%yea old=dock new=dock] :: approved
19+ [%nay old=dock new=dock] :: denied
1720 ==
18−:: $arak: foreign vat tracker
21+:: $rung: reference to upstream commit
1922::
20−:: .rail: upstream tracking state, if any
21−:: .rein: configuration for agents
23++$ rung [=aeon =weft]
24+:: #sync-record: source and destination of a kiln sync
2225::
23−+$ arak
24− $: rail=(unit rail)
25− =rein
26++$ sync-record ::
27+ $: syd=desk :: local desk
28+ her=ship :: foreign ship
29+ sud=desk :: foreign desk
2630 ==
27−:: $rail: upstream tracking state
2831::
29−:: .publisher: Ship that originally published desk, if available
30−:: .paused: is tracking paused? or live
31−:: .ship: upstream ship (could be .our)
32−:: .desk: name of upstream desk
33−:: .aeon: next aeon to pull from upstream
34−:: .next: list of pending commits with future kelvins
32++$ sync-state ::
33+ $: nun=@ta :: nonce
34+ kid=(unit desk) :: has kids desk too?
35+ let=@ud :: next revision
36+ nit=(unit ?) :: automerge or default
37+ hav=(unit @ud) :: update available
38+ yea=? :: update approved
39+ ==
3540::
36−+$ rail
37− $: publisher=(unit ship)
38− paused=?
39− =ship
40− =desk
41− =aeon
42− next=(list rung)
41++$ sync-update
42+ $% [%new for=sync-record rev=@ud]
43+ [%done for=sync-record rev=@ud]
44+ [%drop for=sync-record rev=@ud]
45+ [%pending pending=(set [for=sync-record rev=@ud])]
4346 ==
44−:: $rung: reference to upstream commit
4547::
46−+$ rung [=aeon =weft]
47−:: $rein: diff from desk manifest
48++$ sink (unit [her=@p sud=desk kid=(unit desk) let=@ud])
49+:: +truncate-hash: get last 5 digits of hash and convert to tape
4850::
49−:: .liv: suspended? if suspended, no agents should run
50−:: .add: agents not in manifest that should be running
51−:: .sub: agents in manifest that should not be running
51+++ truncate-hash
52+ |= hash=@uv
53+ ^- tape
54+ (slag 2 <`@uv`(mod hash 0v1.00000)>)
55+:: +report-prep: get data required for reports
5256::
53−+$ rein
54− $: liv=_&
55− add=(set dude)
56− sub=(set dude)
57+++ report-prep
58+ |= [our=@p now=@da]
59+ =/ ego (scot %p our)
60+ =/ wen (scot %da now)
61+ :* .^(rock:tire %cx /[ego]//[wen]/tire)
62+ .^(cone %cx /[ego]//[wen]/domes)
63+ .^((map desk [ship desk]) %gx /[ego]/hood/[wen]/kiln/sources/noun)
64+ .^ (map [desk ship desk] sync-state) %gx
65+ /[ego]/hood/[wen]/kiln/syncs/noun
66+ ==
5767 ==
58−::
59−+$ vat [=desk hash=@uv =cass =arak]
6068:: +report-vats: report on all desk installations
6169::
6270++ report-vats
63− |= [our=@p now=@da]
71+ |= [our=@p now=@da desks=(list desk) filt=@tas verb=?]
6472 ^- tang
65− =+ .^ raz=(list vat)
66− %gx /(scot %p our)/hood/(scot %da now)/kiln/vats/noun
73+ =/ ego (scot %p our)
74+ =/ wen (scot %da now)
75+ =+ prep=[tyr cone sor zyn]=(report-prep our now)
76+ ?: =(%$ filt)
77+ %- zing
78+ %+ turn
79+ ?^ desks
80+ (flop desks)
81+ %+ sort ~(tap in ~(key by tyr.prep))
82+ |= [a=desk b=desk]
83+ ?: |(=(a %kids) =(b %base)) &
84+ ?: |(=(a %base) =(b %kids)) |
85+ (aor b a)
86+ |=(syd=@tas (report-vat prep our now syd verb))
87+ =/ deks=(list [=desk =zest wic=(set weft)])
88+ ?~ desks
89+ %+ sort ~(tap by tyr.prep)
90+ |= [[a=desk *] [b=desk *]]
91+ ?: |(=(a %kids) =(b %base)) &
92+ ?: |(=(a %base) =(b %kids)) |
93+ (aor b a)
94+ %+ murn (flop desks)
95+ |= des=desk
96+ ^- (unit [=desk =zest wic=(set weft)])
97+ ?~ got=(~(get by tyr.prep) des)
98+ ~
99+ `[des u.got]
100+ ?: =(filt %blocking)
101+ =/ base-weft=(unit weft)
102+ %- ~(rep in wic:(~(got by tyr.prep) %base))
103+ |= [=weft out=(unit weft)]
104+ ?~ out
105+ `weft
106+ ?: (lth num.weft num.u.out)
107+ out
108+ `weft
109+ ?~ base-weft ~['%base already up-to-date']
110+ =/ blockers=(list desk)
111+ %+ sort
112+ ^- (list desk)
113+ %+ murn deks
114+ |= [=desk =zest wic=(set weft)]
115+ ^- (unit ^desk)
116+ ?. =(%live zest)
117+ ~
118+ ?: (~(has in wic) u.base-weft)
119+ ~
120+ `desk
121+ aor
122+ ?~ blockers ~['No desks blocking upgrade']
123+ %- zing
124+ ^- (list tang)
125+ :- :~ %+ rap 3
126+ :~ 'These desks are blocking upgrade to [%zuse '
127+ (scot %ud num.u.base-weft)
128+ ']:'
129+ == ==
130+ %+ turn blockers
131+ |=(syd=desk (report-vat prep our now syd verb))
132+ ::
133+ %- zing
134+ %+ turn
135+ ?+ filt !!
136+ %exists
137+ %+ skip deks
138+ |= [syd=desk *]
139+ ?~ got=(~(get by cone.prep) our syd)
140+ &
141+ =(0 let.u.got)
142+ ::
143+ %running
144+ %+ skim deks
145+ |=([* [zest=@tas *]] =(zest %live))
146+ ::
147+ %suspended
148+ %+ skip deks
149+ |= [syd=@tas [zest=@tas *]]
150+ ?| =(syd %kids)
151+ =(zest %live)
152+ ?~ got=(~(get by cone.prep) our syd)
153+ &
154+ =(0 let.u.got)
67155 ==
68− :- (report-kids our now)
69− (turn raz |=(v=vat (report-vat our now v)))
156+ ::
157+ %exists-not
158+ %+ skim deks
159+ |= [syd=desk *]
160+ ?~ got=(~(get by cone.prep) our syd)
161+ |
162+ =(0 let.u.got)
163+ ==
164+ |=([syd=desk *] (report-vat prep our now syd verb))
70165:: +report-vat: report on a single desk installation
71166::
72167++ report-vat
73− |= [our=ship now=@da vat]
74− ^- tank
75− ?: =(ud.cass 0)
76− leaf+"desk does not yet exist: {<desk>}"
77− =/ kel-path
78− /(scot %p our)/[desk]/(scot %da now)/sys/kelvin
168+ |= $: $: tyr=rock:tire =cone sor=(map desk (pair ship desk))
169+ zyn=(map [desk ship desk] sync-state)
170+ ==
171+ our=ship now=@da syd=desk verb=?
172+ ==
173+ |^ ^- tang
174+ =/ ego (scot %p our)
175+ =/ wen (scot %da now)
176+ ?. ((sane %tas) syd)
177+ ~[(cat 3 'insane desk: %' syd)]
178+ ?. (~(has by cone) our syd)
179+ ~[(cat 3 'desk does not yet exist: %' syd)]
180+ =/ hash .^(@uv %cz /[ego]/[syd]/[wen])
181+ ?: =(%kids syd)
182+ ~[(cat 3 '%kids %cz hash: ' (scot %uv hash))]
183+ =/ kel-path /[ego]/[syd]/[wen]/sys/kelvin
79184 ?. .^(? %cu kel-path)
80− leaf+"bad desk: {<desk>}"
81− =+ .^(=weft %cx kel-path)
82− :+ %rose ["" "{<desk>}" "::"]
185+ ~[(cat 3 'bad desk: %' syd)]
186+ =+ .^(=waft %cx kel-path)
83187 ^- tang
84− =/ meb (mergebase-hashes our desk now arak)
85− =/ poz
86− ?~ rail.arak "local"
87− ?:(paused.u.rail.arak "paused" "tracking")
88− =/ sat ?:(liv.rein.arak "running" "suspended")
89− =/ pen
90− ?~ rail.arak "~"
91− <(turn next.u.rail.arak |=([@ lal=@tas num=@] [lal num]))>
92− :~ leaf/"/sys/kelvin: {<[lal num]:weft>}"
93− leaf/"base hash: {?.(=(1 (lent meb)) <meb> <(head meb)>)}"
94− leaf/"%cz hash: {<hash>}"
95− ::
96− leaf/"app status: {sat}"
97− leaf/"force on: {?:(=(~ add.rein.arak) "~" <add.rein.arak>)}"
98− leaf/"force off: {?:(=(~ sub.rein.arak) "~" <sub.rein.arak>)}"
99− ::
100− leaf/"publishing ship: {?~(rail.arak <~> <publisher.u.rail.arak>)}"
101− leaf/"updates: {poz}"
102− leaf/"source ship: {?~(rail.arak <~> <ship.u.rail.arak>)}"
103− leaf/"source desk: {?~(rail.arak <~> <desk.u.rail.arak>)}"
104− leaf/"source aeon: {?~(rail.arak <~> <aeon.u.rail.arak>)}"
105− leaf/"pending updates: {pen}"
188+ =/ =sink
189+ ?~ s=(~(get by sor) syd)
190+ ~
191+ ?~ z=(~(get by zyn) syd u.s)
192+ ~
193+ `[p.u.s q.u.s [kid let]:u.z]
194+ =/ meb=(list @uv)
195+ ?~ sink ~[hash]
196+ %+ turn
197+ .^ (list tako) %cs
198+ /[ego]/[syd]/[wen]/base/(scot %p her.u.sink)/[sud.u.sink]
199+ ==
200+ |=(=tako .^(@uv %cs /[ego]/[syd]/[wen]/hash/(scot %uv tako)))
201+ =/ dek (~(got by tyr) syd)
202+ =/ sat
203+ ?- zest.dek
204+ %live 'running'
205+ %dead 'suspended'
206+ %held 'suspended until next update'
207+ ==
208+ =/ kul=cord (print-wefts (waft-to-wefts waft))
209+ =/ ese=cord
210+ ?:(.^(? %cx /[ego]//[wen]/esse/[syd]) 'yes' 'no')
211+ =/ pax=path /(scot %p our)/[syd]/(scot %da now)
212+ ?. verb
213+ :~ '::'
214+ =+ .^(exist=? cu+(weld pax /desk/bill))
215+ ?. exist ' /desk/bill: missing'
216+ =+ .^(dudes=(list dude:gall) cx+(weld pax /desk/bill))
217+ (cat 3 ' /desk/bill: ' (crip "{<dudes>}"))
218+ (cat 3 ' pending updates: ' (print-wefts wic.dek))
219+ (cat 3 ' source ship: ' ?~(sink '~' (scot %p her.u.sink)))
220+ (cat 3 ' app status: ' sat)
221+ (cat 3 ' essential desk: ' ese)
222+ (cat 3 ' %cz hash ends in: ' (print-shorthash hash))
223+ (cat 3 ' /sys/kelvin: ' (print-wefts (waft-to-wefts waft)))
224+ (cat 3 '%' syd)
225+ ==
226+ ::
227+ =/ [on=(list @tas) of=(list @tas)]
228+ =/ [on=(list @tas) of=(list @tas)]
229+ %- ~(rep by ren:(~(got by cone) our syd))
230+ |= [[=dude:gall is-on=?] on=(list @tas) of=(list @tas)]
231+ ?: is-on
232+ [[dude on] of]
233+ [on [dude of]]
234+ [(sort on aor) (sort of aor)]
235+ :~ '::'
236+ (cat 3 ' pending updates: ' (print-wefts wic.dek))
237+ %^ cat 3 ' kids desk: ' ?~ sink '~'
238+ ?~ kid.u.sink '~'
239+ (cat 3 '%' u.kid.u.sink)
240+ (cat 3 ' source aeon: ' ?~(sink '~' (scot %ud let.u.sink)))
241+ (cat 3 ' source desk: ' ?~(sink '~' (cat 3 '%' sud.u.sink)))
242+ (cat 3 ' source ship: ' ?~(sink '~' (scot %p her.u.sink)))
243+ (cat 3 ' updates: ' ?~(sink 'local' 'remote'))
244+ %^ cat 3 ' publishing ship: ' ?~ got=(get-publisher our syd now)
245+ '~'
246+ (scot %p u.got)
247+ ::
248+ (cat 3 ' force off: ' (print-agents of))
249+ (cat 3 ' force on: ' (print-agents on))
250+ (cat 3 ' app status: ' sat)
251+ (cat 3 ' essential desk: ' ese)
252+ ::
253+ (cat 3 ' %cz hash: ' (scot %uv hash))
254+ (cat 3 ' base hash: ' (print-mergebases meb))
255+ (cat 3 ' /sys/kelvin: ' (print-wefts (waft-to-wefts waft)))
256+ (cat 3 '%' syd)
106257 ==
258+ ++ print-wefts
259+ |= wefts=(set weft)
260+ ^- @t
261+ ?: =(~ wefts)
262+ '~'
263+ %+ roll (sort ~(tap in wefts) aor)
264+ |= [=weft out=@t]
265+ ?: =('' out)
266+ (rap 3 '[%' lal.weft ' ' (scot %ud num.weft) ']' ~)
267+ (rap 3 out ' [%' lal.weft ' ' (scot %ud num.weft) ']' ~)
268+ ::
269+ ++ print-shorthash
270+ |= hash=@uv
271+ ^- @t
272+ (crip ((v-co:co 5) (end [0 25] hash)))
273+ ::
274+ ++ print-mergebases
275+ |= hashes=(list @uv)
276+ ^- @t
277+ ?~ hashes
278+ '~'
279+ ?~ t.hashes
280+ (scot %uv i.hashes)
281+ %+ roll `(list @uv)`hashes
282+ |= [hash=@uv out=@t]
283+ ?: =('' out)
284+ (print-shorthash hash)
285+ (rap 3 out ' ' (print-shorthash hash) ~)
286+ ::
287+ ++ print-agents
288+ |= agents=(list @tas)
289+ ^- @t
290+ ?~ agents
291+ '~'
292+ %+ roll `(list @tas)`agents
293+ |= [agent=@tas out=@tas]
294+ ?: =('' out)
295+ (cat 3 '%' agent)
296+ (rap 3 out ' %' agent ~)
297+ --
107298:: +report-kids: non-vat cz hash report for kids desk
108299::
109300++ report-kids
110301 |= [our=ship now=@da]
111302 ^- tank
112− =/ dek %kids
303+ =/ syd %kids
113304 =/ ego (scot %p our)
114305 =/ wen (scot %da now)
115− ?. (~(has in .^((set desk) %cd /[ego]//[wen])) dek)
116− leaf/"no %kids desk"
117− =+ .^(hash=@uv %cz /[ego]/[dek]/[wen])
118− leaf/"%kids %cz hash: {<hash>}"
119−:: +read-kelvin-foreign: read /sys/kelvin from a foreign desk
120−::
121−++ read-kelvin-foreign
122− |= [=ship =desk =aeon]
123− ^- weft
124− ~| read-foreign-kelvin/+<
125− =/ her (scot %p ship)
126− =/ syd (scot %tas desk)
127− =/ yon (scot %ud aeon)
128− ::
129− =/ dom .^(dome cv/~[her syd yon])
130− =/ tak (scot %uv (~(got by hit.dom) let.dom))
131− =/ yak .^(yaki cs/~[her syd yon %yaki tak])
132− =/ lob (scot %uv (~(got by q.yak) /sys/kelvin))
133− =/ bob .^(blob cs/~[her syd yon %blob lob])
134− ::
135− ;; weft
136− ?- -.bob
137− %direct q.q.bob
138− %delta q.r.bob
139− ==
140−:: +read-kelvin-local: read /sys/kelvin from a local desk
141−::
142−++ read-kelvin-local
143− |= [our=ship =desk now=@da]
144− ^- (unit weft)
145− ~| read-kelvin-local+desk
146− =/ pax (en-beam [our desk da+now] /sys/kelvin)
147− ?. .^(? cu/pax)
148− ~
149− [~ .^(weft cx/pax)]
306+ ?. (~(has in .^((set desk) %cd /[ego]//[wen])) syd)
307+ 'no %kids desk'
308+ =+ .^(hash=@uv %cz /[ego]/[syd]/[wen])
309+ (cat 3 '%kids %cz hash: ' (scot %uv hash))
150310:: +read-bill-foreign: read /desk/bill from a foreign desk
151311::
152312++ read-bill-foreign
@@ -157,20 +317,15 @@
157317 =/ syd (scot %tas desk)
158318 =/ yon (scot %ud aeon)
159319 ::
160− =/ dom .^(dome cv/~[her syd yon])
320+ =/ dom .^(domo cv/~[her syd yon])
161321 =/ tak ~| aeons=~(key by hit.dom)
162322 (scot %uv (~(got by hit.dom) aeon))
163323 =/ yak .^(yaki cs/~[her syd yon %yaki tak])
164324 =/ fil (~(get by q.yak) /desk/bill)
165325 ?~ fil ~
166326 =/ lob (scot %uv u.fil)
167− =/ bob .^(blob cs/~[her syd yon %blob lob])
168− ::
169− ;; (list dude)
170− ?- -.bob
171− %direct q.q.bob
172− %delta q.r.bob
173− ==
327+ =/ peg .^(page cs/~[her syd yon %blob lob])
328+ ;;((list dude) q.peg)
174329:: +read-bill: read contents of /desk/bill manifest
175330::
176331++ read-bill
@@ -179,21 +334,6 @@
179334 ?. .^(? cu/pax)
180335 *(list dude)
181336 .^((list dude) cx/pax)
182−:: +adjust-dudes: which agents should be started and stopped
183−::
184−:: Will ask Gall to start agents that it's already running
185−:: but that should be ok, and might be safer in case other
186−:: unprocessed moves would have turned them off.
187−::
188−++ adjust-dudes
189− |= $: local=[our=ship =desk now=@da]
190− =rein
191− ==
192− ^- [jolt=(list dude) idle=(list dude)]
193− =/ all=(list dude) (read-bill local)
194− =/ want (get-apps-want local all rein)
195− =/ have (get-apps-live local)
196− [want (skip have ~(has in (sy want)))]
197337::
198338++ get-remote-diff
199339 |= [our=ship here=desk now=@da her=ship there=desk when=aeon]
@@ -219,39 +359,19 @@
219359 |= [our=ship =desk now=@da]
220360 ^- (list [=dude live=?])
221361 %~ tap in
222− .^((set [=dude live=?]) ge+/(scot %p our)/[desk]/(scot %da now))
223−:: +get-apps-want: find which apps should be running on a desk
224−::
225−++ get-apps-want
226− |= [local=[our=ship =desk now=@da] duz=(list dude) =rein]
227− ^- (list dude)
228− ?. liv.rein ~
229− ?. |(=(`zuse+zuse (read-kelvin-local local)) =(%base desk.local)) ~
230− =. duz (skip duz ~(has in sub.rein))
231− =. duz (weld duz (skip ~(tap in add.rein) ~(has in (sy duz))))
232− duz
362+ .^((set [=dude live=?]) ge+/(scot %p our)/[desk]/(scot %da now)/$)
233363::
234364++ mergebase-hashes
235− |= [our=@p =desk now=@da =arak]
236− ?~ rail.arak
237− ~
238− =/ her (scot %p ship.u.rail.arak)
365+ |= [our=@p syd=desk now=@da her=ship sud=desk]
366+ =/ her (scot %p her)
239367 =/ ego (scot %p our)
240368 =/ wen (scot %da now)
241− %+ turn .^((list tako) %cs ~[ego desk wen %base her desk.u.rail.arak])
242− |=(=tako .^(@uv %cs ~[ego desk wen %hash (scot %uv tako)]))
369+ %+ turn .^((list tako) %cs /[ego]/[syd]/[wen]/base/[her]/[sud])
370+ |=(=tako .^(@uv %cs /[ego]/[syd]/[wen]/hash/(scot %uv tako)))
243371::
244372++ enjs
245373 =, enjs:format
246374 |%
247− ++ vats
248− |= v=(list ^vat)
249− ^- json
250− %- pairs
251− %+ turn v
252− |= va=^vat
253− [desk.va (vat va)]
254− ::
255375 ++ tim
256376 |= t=@
257377 ^- json
@@ -264,15 +384,6 @@
264384 da+(tim da.c)
265385 ==
266386 ::
267− ++ vat
268− |= v=^vat
269− %- pairs
270− :~ desk+s+desk.v
271− hash+s+(scot %uv hash.v)
272− cass+(cass cass.v)
273− arak+(arak arak.v)
274− ==
275− ::
276387 ++ weft
277388 |= w=^weft
278389 %- pairs
@@ -286,30 +397,5 @@
286397 :~ aeon+(numb aeon.r)
287398 weft+(weft weft.r)
288399 ==
289− ::
290− ++ rein
291− |= r=^rein
292− %- pairs
293− :~ add+a+(turn ~(tap in add.r) (lead %s))
294− sub+a+(turn ~(tap in sub.r) (lead %s))
295− ==
296− ::
297− ++ arak
298− |= a=^arak
299− %- pairs
300− :~ rail+?~(rail.a ~ (rail u.rail.a))
301− rein+(rein rein.a)
302− ==
303− ::
304− ++ rail
305− |= r=^rail
306− %- pairs
307− :~ ship+s+(scot %p ship.r)
308− publisher+?~(publisher.r ~ s+(scot %p u.publisher.r))
309− desk+s+desk.r
310− paused+b+paused.r
311− aeon+(numb aeon.r)
312− next+a+(turn next.r rung)
313− ==
314400 --
315401--
base-desk/sur/ring.hoon+1−1
@@ -15,7 +15,7 @@
1515 :: resistance...but if your private keys are compromised, your
1616 :: adversary can determine which signatures you made.
1717 ::
18− y=(unit @udpoint)
18+ y=(unit @uxpoint)
1919 ==
2020:: +ring-signature: higher level ring signature type
2121::
base-desk/sur/sole.hoon+2−1
@@ -3,8 +3,9 @@
33 ::
44^?
55|%
6++$ sole-id [who=@p ses=@ta]
67+$ sole-action :: sole to app
7− $: id=@ta :: duct id
8+ $: id=sole-id :: session id
89 $= dat
910 $% :: [%abo ~] :: reset interaction
1011 [%det sole-change] :: command line edit
base-desk/sur/spider.hoon+14−1
@@ -1,7 +1,7 @@
11/+ libstrand=strand
22=, strand=strand:libstrand
33|%
4−+$ thread $-(vase _*form:(strand ,vase))
4++$ thread $-(vase shed:khan)
55+$ input [=tid =cage]
66+$ tid tid:strand
77+$ bowl bowl:strand
@@ -11,4 +11,17 @@
1111 %nonexistent :: 404
1212 %offline :: 504
1313 ==
14++$ start-args
15+ $: parent=(unit tid)
16+ use=(unit tid)
17+ =beak
18+ file=term
19+ =vase
20+ ==
21++$ inline-args
22+ $: parent=(unit tid)
23+ use=(unit tid)
24+ =beak
25+ =shed:khan
26+ ==
1427--
base-desk/sur/sss.hoonnew file+39
@@ -0,0 +1,39 @@
1+|%
2+++ lake
3+ |$ [rock wave]
4+ $_ ^?
5+ |%
6+ ++ name *term
7+ +$ rock ^rock
8+ +$ wave ^wave
9+ ++ wash |~ [rock wave] *rock
10+ --
11++$ aeon @ud
12++$ dude dude:agent:gall
13+++ poke
14+ |%
15+ ++ request
16+ |* paths=mold
17+ $: path=paths
18+ =dude
19+ ==
20+ ++ response
21+ |* [=(lake) paths=mold]
22+ $: path=paths
23+ =dude
24+ $% [what=%tomb ~]
25+ [what=%rock =aeon =rock:lake]
26+ [what=%wave =aeon =wave:lake]
27+ == ==
28+ ++ on-rock
29+ |* [=(lake) paths=mold]
30+ $: path=paths
31+ src=ship
32+ from=dude
33+ stale=?
34+ fail=?
35+ =rock:lake
36+ wave=(unit wave:lake)
37+ ==
38+ --
39+--
base-desk/sur/story.hoonnew file+9
@@ -0,0 +1,9 @@
1+^?
2+|%
3++$ prose [title=@t body=@t]
4++$ proses (set prose)
5++$ story (jug tako:clay prose) :: set len > 1 means conflicting messages have been assigned
6++$ chapter [tako:clay proses] :: prose entry type
7++$ cash $%([%tako p=tako:clay] case) :: used in generators to accept a tako directly as well
8++$ story-diff [additions=story deletions=story]
9+--
base-desk/sur/verb.hoon+37−1
@@ -9,4 +9,40 @@
99 [%on-arvo =wire vane=term sign=term]
1010 [%on-fail =term]
1111 ==
12−--
12+::
13++$ event-plus
14+ $: act=@ud
15+ now=@da
16+ src=@p
17+ sap=path
18+ =cause
19+ effects=(list effect)
20+ ==
21+::
22++$ cause
23+ $% [%on-init ~]
24+ [%on-load ~]
25+ [%on-poke =mark mug=@ux]
26+ [%on-watch =path]
27+ [%on-leave =path]
28+ [%on-agent =wire =sign]
29+ [%on-arvo =wire vane=term sign=term]
30+ [%on-fail =term]
31+ ==
32+::
33++$ sign
34+ $% [%poke-ack ack=?]
35+ [%watch-ack ack=?]
36+ [%kick ~]
37+ [%fact =mark mug=@ux]
38+ ==
39+::
40++$ effect
41+ $% [%poke =wire =gill:gall =mark mug=@ux]
42+ [%watch =wire =gill:gall =path]
43+ [%leave =wire =gill:gall]
44+ [%fact paths=(list path) =mark mug=@ux]
45+ [%kick paths=(list path)]
46+ [%arvo =wire vane=term task=term]
47+ ==
48+--
bin/commit.shnew file+24
@@ -0,0 +1,24 @@
1+#!/bin/bash
2+
3+usage() { printf "Usage: $0 URBIT_DESK_DIRECTORY\n" 1>&2; exit 1; }
4+
5+cdir=$(dirname $0)
6+
7+if [ $# -eq 0 ]; then
8+ usage
9+ exit 2
10+fi
11+DESK_DIR=${@: -1}
12+DESK_DIR="${DESK_DIR/#\~/$HOME}"
13+PIER=$(dirname $DESK_DIR)
14+DESK=$(basename $DESK_DIR)
15+
16+port=$(cat $PIER/.http.ports | grep loopback | tr -s ' ' '\n' | head -n 1)
17+
18+lensa() {
19+ curl -s \
20+ --data "{\"source\":{\"dojo\":\"$2\"},\"sink\":{\"app\":\"$1\"}}" \
21+ "http://localhost:$port" | xargs printf %s | sed 's/\\n/\n/g'
22+}
23+
24+lensa 'hood' "+hood/commit %$DESK"
bin/get_glob.shnew file+19
@@ -0,0 +1,19 @@
1+#!/bin/bash
2+
3+usage() { printf "Usage: $0 URBIT_GLOBBER_DESK_DIRECTORY" 1>&2; exit 1; }
4+
5+cdir=$(dirname $0)
6+
7+if [ $# -eq 0 ]; then
8+ usage
9+ exit 2
10+fi
11+DESK="${1//\~/$HOME}"
12+GLOBS="$DESK/../.urb/put"
13+GLOB=$(ls -t $GLOBS | head -1)
14+TARGET_GLOBS="$cdir"/../globs/
15+mkdir -p $TARGET_GLOBS
16+cp "$GLOBS/$GLOB" $TARGET_GLOBS/
17+HASH="${GLOB//glob-/}"
18+HASH="${HASH//.glob/}"
19+echo $HASH
bin/install.shnew file+82
@@ -0,0 +1,82 @@
1+#!/bin/bash
2+#
3+# Taken from: https://github.com/timlucmiptev/btc-agents/blob/master/install.sh
4+# by ~timluc-miptev
5+#
6+# Modified HEAVILY
7+#
8+usage() { printf "Usage: $0 [-w] [-g] URBIT_DESK_DIRECTORY\n(-w: flag to watch and live copy code)\n(-g: install built ui to globber desk)\n" 1>&2; exit 1; }
9+
10+cdir=$(dirname $0)
11+
12+if [ $# -eq 0 ]; then
13+ usage
14+ exit 2
15+fi
16+DESK_DIR=${@: -1}
17+DESK_DIR="${DESK_DIR/#\~/$HOME}"
18+PIER=$(dirname $DESK_DIR)
19+DESK=$(basename $DESK_DIR)
20+EXCLUDE_FILE="${cdir}"/../config/ignore_files_on_install.txt
21+
22+port=$(cat $PIER/.http.ports | grep loopback | tr -s ' ' '\n' | head -n 1)
23+
24+lensd() {
25+ curl -s \
26+ --data "{\"source\":{\"dojo\":\"$1\"},\"sink\":{\"stdout\":null}}" \
27+ "http://localhost:$port" | xargs printf %s | sed 's/\\n/\n/g'
28+}
29+
30+lensa() {
31+ curl -s \
32+ --data "{\"source\":{\"dojo\":\"$2\"},\"sink\":{\"app\":\"$1\"}}" \
33+ "http://localhost:$port" | xargs printf %s | sed 's/\\n/\n/g'
34+}
35+
36+sync() {
37+ rsync -r --copy-links --exclude-from=$EXCLUDE_FILE "${cdir}"/../base-desk/* $DESK_DIR/
38+ rsync -r --copy-links --exclude-from=$EXCLUDE_FILE "${cdir}"/../docs-dev-desk/* $DESK_DIR/
39+ rsync -r --copy-links --exclude-from=$EXCLUDE_FILE "${cdir}"/../desk/* $DESK_DIR/
40+ if [ "$GLOBBER" ]; then
41+ rsync -r --copy-links "${cdir}"/../ui/dist/* $DESK_DIR/astrolabe
42+ fi
43+}
44+
45+
46+while getopts "wg" opt; do
47+ case ${opt} in
48+ w) WATCH_MODE="true"
49+ ;;
50+ g) GLOBBER="true"
51+ ;;
52+ *) usage
53+ ;;
54+ esac
55+done
56+
57+if [ -z "$WATCH_MODE" ]; then
58+ echo "Installed %astrolabe to ${DESK_DIR}"
59+ rm -r $DESK_DIR/*
60+ sync
61+ lensa 'hood' "+hood/commit %$DESK"
62+ if [ "$GLOBBER" ]; then
63+ lensd '-garden!make-glob %globber /astrolabe'
64+ GLOBS="$PIER/.urb/put"
65+ GLOB=$(ls -t $GLOBS | head -1)
66+ TARGET_GLOBS="$cdir"/../globs/
67+ mkdir -p $TARGET_GLOBS
68+ cp "$GLOBS/$GLOB" $TARGET_GLOBS/
69+ echo "copied from $GLOBS to $TARGET_GLOBS"
70+ HASH="${GLOB//glob-/}"
71+ HASH="${HASH//.glob/}"
72+ echo $HASH
73+ fi
74+else
75+ echo "Watching for changes to copy to ${DESK_DIR}..."
76+ rm -r $DESK_DIR/*
77+ while [ 0 ]
78+ do
79+ sleep 0.8
80+ sync
81+ done
82+fi
bin/make_glob.pynew file+208
@@ -0,0 +1,208 @@
1+#!/usr/bin/env python3
2+
3+import hashlib
4+import sys
5+from pathlib import Path
6+from urllib.parse import quote
7+
8+from noun import Cell, deep, intbytes, mug
9+
10+MIME_TYPES = {
11+ "css": "text/css",
12+ "gif": "image/gif",
13+ "html": "text/html",
14+ "ico": "image/x-icon",
15+ "jpeg": "image/jpeg",
16+ "jpg": "image/jpeg",
17+ "js": "application/javascript",
18+ "json": "application/json",
19+ "png": "image/png",
20+ "svg": "image/svg+xml",
21+ "ttf": "font/ttf",
22+ "webmanifest": "application/manifest+json",
23+ "woff": "font/woff",
24+ "woff2": "font/woff2",
25+}
26+BASE32 = "0123456789abcdefghijklmnopqrstuv"
27+
28+
29+class BitWriter:
30+ def __init__(self):
31+ self.output = bytearray()
32+ self.buffer = 0
33+ self.used = 0
34+ self.cursor = 0
35+
36+ def write(self, value, count):
37+ if count == 0:
38+ return
39+ self.buffer |= value << self.used
40+ self.used += count
41+ self.cursor += count
42+ byte_count = self.used // 8
43+ if byte_count:
44+ self.output.extend(self.buffer.to_bytes((self.used + 7) // 8, "little")[:byte_count])
45+ self.buffer >>= byte_count * 8
46+ self.used -= byte_count * 8
47+
48+ def finish(self):
49+ if self.used:
50+ self.output.append(self.buffer)
51+ self.buffer = 0
52+ self.used = 0
53+ return bytes(self.output)
54+
55+
56+def jam_bytes(value):
57+ writer = BitWriter()
58+ references = {}
59+
60+ def save(noun):
61+ references[noun] = writer.cursor
62+
63+ def mat(atom):
64+ if atom == 0:
65+ writer.write(1, 1)
66+ return
67+ atom_length = atom.bit_length()
68+ length_size = atom_length.bit_length()
69+ writer.write(1 << length_size, length_size + 1)
70+ writer.write(atom_length & ((1 << (length_size - 1)) - 1), length_size - 1)
71+ writer.write(atom, atom_length)
72+
73+ def back(reference):
74+ writer.write(3, 2)
75+ mat(reference)
76+
77+ def serialize(noun):
78+ duplicate = references.get(noun)
79+ if deep(noun):
80+ if duplicate is not None:
81+ back(duplicate)
82+ return
83+ save(noun)
84+ writer.write(1, 1)
85+ writer.write(0, 1)
86+ serialize(noun.head)
87+ serialize(noun.tail)
88+ return
89+ if duplicate is not None:
90+ atom_size = noun.bit_length()
91+ reference_size = duplicate.bit_length()
92+ if atom_size >= reference_size:
93+ back(duplicate)
94+ return
95+ save(noun)
96+ writer.write(0, 1)
97+ mat(noun)
98+
99+ serialize(value)
100+ return writer.finish()
101+
102+
103+def cord(value):
104+ return int.from_bytes(value.encode(), "little")
105+
106+
107+def path_noun(parts):
108+ result = 0
109+ for part in reversed(parts):
110+ result = Cell(cord(part), result)
111+ return result
112+
113+
114+def dor(a, b):
115+ if a == b:
116+ return True
117+ if deep(a):
118+ if not deep(b):
119+ return False
120+ if a.head == b.head:
121+ return dor(a.tail, b.tail)
122+ return dor(a.head, b.head)
123+ if deep(b):
124+ return True
125+ return a < b
126+
127+
128+def gor(a, b):
129+ a_mug = mug(a)
130+ b_mug = mug(b)
131+ return dor(a, b) if a_mug == b_mug else a_mug < b_mug
132+
133+
134+def map_put(tree, entry):
135+ if tree == 0:
136+ return Cell(entry, Cell(0, 0))
137+ node = tree.head
138+ if entry.head == node.head:
139+ return Cell(entry, tree.tail)
140+ left = tree.tail.head
141+ right = tree.tail.tail
142+ if gor(entry.head, node.head):
143+ return Cell(node, Cell(map_put(left, entry), right))
144+ return Cell(node, Cell(left, map_put(right, entry)))
145+
146+
147+def shas(salt, serialized):
148+ value_hash = int.from_bytes(hashlib.sha256(serialized).digest(), "little")
149+ length = max(32, len(intbytes(salt)))
150+ digest = hashlib.sha256((salt ^ value_hash).to_bytes(length, "little")).digest()
151+ return int.from_bytes(digest, "little")
152+
153+
154+def sham(serialized):
155+ hashed = shas(cord("sham"), serialized)
156+ mask = (1 << 128) - 1
157+ return (hashed & mask) ^ (hashed >> 128)
158+
159+
160+def scow_uv(value):
161+ if value == 0:
162+ return "0v0"
163+ digits = []
164+ while value:
165+ value, digit = divmod(value, 32)
166+ digits.append(BASE32[digit])
167+ digits = "".join(reversed(digits))
168+ first_length = (len(digits) - 1) % 5 + 1
169+ groups = [digits[:first_length]]
170+ groups.extend(digits[i:i + 5] for i in range(first_length, len(digits), 5))
171+ return "0v" + ".".join(groups)
172+
173+
174+def file_entry(root, file_path):
175+ relative = file_path.relative_to(root)
176+ parts = []
177+ for part in relative.parts:
178+ parts.extend(quote(segment, safe="-_~") for segment in part.split("."))
179+ extension = relative.suffix.removeprefix(".").lower()
180+ if extension not in MIME_TYPES:
181+ raise ValueError(f"no MIME type configured for {relative}")
182+ data = file_path.read_bytes()
183+ mime = Cell(path_noun(MIME_TYPES[extension].split("/")), Cell(len(data), int.from_bytes(data, "little")))
184+ return Cell(path_noun(parts), mime)
185+
186+
187+def make_glob(source, destination):
188+ root = Path(source)
189+ files = sorted((path for path in root.rglob("*") if path.is_file()), key=lambda path: path.as_posix())
190+ if not (root / "index.html").is_file():
191+ raise ValueError("glob source must contain index.html")
192+ glob = 0
193+ for file_path in files:
194+ glob = map_put(glob, file_entry(root, file_path))
195+ serialized = jam_bytes(glob)
196+ glob_hash = scow_uv(sham(serialized))
197+ output = Path(destination)
198+ output.mkdir(parents=True, exist_ok=True)
199+ filename = f"glob-{glob_hash}.glob"
200+ (output / filename).write_bytes(serialized)
201+ (output / "hash").write_text(glob_hash + "\n")
202+ print(filename)
203+
204+
205+if __name__ == "__main__":
206+ if len(sys.argv) != 3:
207+ raise SystemExit(f"usage: {sys.argv[0]} SOURCE_DIRECTORY OUTPUT_DIRECTORY")
208+ make_glob(sys.argv[1], sys.argv[2])
desk/app/astrolabe.hoon+298−17
@@ -1,15 +1,12 @@
1−/- astrolabe
2−/+ naive, default-agent, dbug, agentio
1+/- *astrolabe
2+/+ *astrolabe, *search, slib=state
3+/+ *mip, naive, default-agent, dbug, agentio
34/$ udon-to-docu %udon %docu
45|%
5−+$ versioned-state
6− $% state-0
7− ==
8−+$ state-0 [%0 data=(map @p @t)]
96+$ card card:agent:gall
107--
118%- agent:dbug
12−=| state-0
9+=| state-latest
1310=* state -
1411^- agent:gall
1512=<
@@ -20,10 +17,29 @@
2017::
2118++ on-init
2219 ^- (quip card _this)
23− `this
20+ :_ this
21+ :~ ug-handler-card:hc
22+ groups-link-patch-card:hc
23+ talk-link-patch-card:hc
24+ az-events-card:hc
25+ ==
2426::
25−++ on-save on-save:def
26−++ on-load on-load:def
27+++ on-save !>(state)
28+++ on-load
29+ |= old-state=vase
30+ ^- (quip card _this)
31+ =/ old !<(versioned-state old-state)
32+ =/ [cards-01=(list card) new=state-latest]
33+ ?. |(?=(?(%0 %1 %2 %3) -.old) (lth bump.old bump)) `old
34+ (on-naive-state:hc get-nas:hc)
35+ ?> ?=(%4 -.new)
36+ =/ cards=(list card)
37+ :~ ug-handler-card:hc
38+ groups-link-patch-card:hc
39+ talk-link-patch-card:hc
40+ ==
41+ =. cards (weld cards-01 cards)
42+ [cards this(state new)]
2743++ on-poke on-poke:def
2844++ on-watch on-watch:def
2945++ on-leave on-leave:def
@@ -32,10 +48,29 @@
3248 |= =path
3349 ^- (unit (unit cage))
3450 ?+ path (on-peek:def path)
51+ [%x %nop ~]
52+ ``noun+!>(~)
3553 [%x %point @ ~]
36− =, bowl
37− :- ~ :- ~ :- %astrolabe-point
38− !> .^(upoint:astrolabe %gx (scrio:hc %azimuth /point/[&3.path]/noun))
54+ ``astrolabe-point+!>((get-point:hc &3.path))
55+ [%x %point @ %spawned ?(~ [spawned-filter ~])]
56+ =/ =ship `@p`(slav %p &3.path)
57+ =/ filter t.t.t.t.path
58+ =/ arg ?~(filter %all -.filter)
59+ ``astrolabe-point-set+!>((get-spawned-points:hc ship arg))
60+ [%x %search %patp @ ?(~ [%narrow ~])]
61+ =/ =search-text (trip &4.path)
62+ ?~ search-text ~|(%search-predicted-too-broad !!)
63+ =/ expand-search =(t.t.t.path ~)
64+ ``astrolabe-point-set+!>((search-opoints-patp:hc search-text expand-search))
65+ [%x %search %sigil @ ~]
66+ =/ =search-text (trip &4.path)
67+ ?~ search-text ~|(%search-predicted-too-broad !!)
68+ ``astrolabe-point-set+!>((search-opoints-sigil:hc search-text))
69+ [%x %peers ~]
70+ =/ peers .^((map ship ?(%alien %known)) %ax (scrio:hc %$ /peers))
71+ ``astrolabe-point-set+!>((turn ~(tap in peers) head))
72+ [%x %chart-data ~]
73+ ``json+!>(get-chart-data:hc)
3974 [%x %doc ^]
4075 =/ doc-path=^path t.t.path
4176 =/ doc (read-doc:hc doc-path)
@@ -43,22 +78,268 @@
4378 `~
4479 ``json+!>(s+u.doc)
4580 ==
81+++ on-agent
82+ |= [=wire =sign:agent:gall]
83+ ^- (quip card _this)
84+ |^
85+ ?+ wire (on-agent:def wire sign)
86+ [%azimuth-events ~] (azimuth-event sign)
87+ ==
88+ ::
89+ ++ azimuth-event
90+ |= =sign:agent:gall
91+ ^- (quip card _this)
92+ ?+ -.sign [~ this]
93+ %watch-ack
94+ ?~ p.sign [~ this]
95+ =/ =tank leaf+"{(trip dap.bowl)} couldn't start listen to %azimuth"
96+ %- (slog tank u.p.sign)
97+ [~ this]
98+ ::
99+ %fact
100+ ?+ p.cage.sign (on-agent:def wire sign)
101+ %naive-diffs
102+ =+ !<(=diff:naive q.cage.sign)
103+ =^ cards state
104+ (on-naive-diff:hc diff)
105+ [cards this]
106+ ::
107+ %naive-state
108+ :: ~& > %received-azimuth-state
109+ :: =+ !<([nas=^state:naive =indices:dice] q.cage.sign)
110+ =+ !<([nas=^state:naive indices=*] q.cage.sign)
111+ =^ cards state
112+ (on-naive-state:hc nas)
113+ [cards this]
114+ ==
115+ ==
116+ --
46117::
47−++ on-agent on-agent:def
48−++ on-arvo on-arvo:def
49−++ on-fail on-fail:def
118+++ on-arvo on-arvo:def
119+++ on-fail on-fail:def
50120--
51121::
122+:: Helper Core
52123|_ =bowl:gall
53124++ scrio ~(scry agentio bowl)
125+++ az-events-card [%pass /azimuth-events %agent [our.bowl %azimuth] %watch /event]
126+++ get-nas .^(^state:naive %gx (scrio %azimuth /nas/noun))
127+++ put-in-fropoints
128+ |= =ship
129+ ^- _state
130+ =. fopoints
131+ (put:ors fopoints (to-q ship) ~)
132+ =. ropoints
133+ (put:ors ropoints (switch-words (to-q ship)) ~)
134+ state
135+::
136+++ put-in-spawn-mip
137+ |= [child=ship nas=^state:naive]
138+ ^- _state
139+ =/ =npoint (get-npoint-from-nas child nas)
140+ (put-in-spawn-mip:slib child npoint state)
141+::
142+++ on-naive-state
143+ |= nas=^state:naive
144+ ^- (quip card _state)
145+ =+ points=points.nas :: =points, eh?
146+ :- ~
147+ |-
148+ ^- _state
149+ ?~ points state
150+ =/ =ship -.n.points
151+ =. state (put-in-fropoints ship)
152+ =. state (put-in-spawn-mip ship nas)
153+ $(points l.points, state $(points r.points))
154+::
155+++ on-naive-diff
156+ |= =diff:naive
157+ ^- (quip card _state)
158+ :: ~& %+ weld "received diff:naive: {<-.diff>}"
159+ :: ?+ -.diff ""
160+ :: %nonce " ship: {<ship.diff>}"
161+ :: %tx " from: {<ship.from.tx.raw-tx.diff>} - {<+<.tx.raw-tx.diff>}"
162+ :: %point " ship: {<ship.diff>} - {<+>-.diff>}"
163+ :: ==
164+ =? state ?=([%tx [* * * %spawn ship *] *] diff)
165+ %- put-in-fropoints
166+ ship.tx.raw-tx.diff
167+ =? state ?=([%point @ %owner *] diff)
168+ %- put-in-fropoints
169+ ship.diff
170+ =? state ?=([%point @ *] diff)
171+ %+ put-in-spawn-mip
172+ ship.diff
173+ get-nas
174+ `state
175+::
176+++ is-spawn-tx
177+ |= =diff:naive
178+ ^- ?
179+ ?= [%tx [* * * %spawn ship *] *] diff
180+::
181+++ get-unpoint-term
182+ |= ship-name=term
183+ .^(unpoint %gx (scrio %azimuth /point/[ship-name]/noun))
184+::
185+++ get-unpoint
186+ |= =ship
187+ (get-unpoint-term (scot %p ship))
188+::
189+++ get-point
190+ |= ship-name=term
191+ ^- point
192+ =/ =ship `@p`(slav %p ship-name)
193+ =/ unpoint (get-unpoint-term ship-name)
194+ :* ship
195+ unpoint
196+ (spa-count ship)
197+ (sponsor-chain ship unpoint)
198+ (probable-dominion ship unpoint)
199+ ==
200+++ get-npoint-from-nas
201+ |= [=ship nas=^state:naive]
202+ ^- npoint
203+ (need (get:orm:naive points.nas ship))
204+::
205+++ run-spawned-points
206+ |* [agg=mold targ=ship nas=^state:naive filter=spawned-filter]
207+ |= f=$-([agg [ship npoint]] agg)
208+ ^- agg
209+ =| =agg
210+ ?. ?=(?(%czar %king) (clan:title targ))
211+ agg
212+ =+ points=points.nas
213+ |-
214+ ^- _agg
215+ ?~ points
216+ agg
217+ =* n -.n.points
218+ =/ gt=? (por:naive targ n)
219+ ?: |(=(targ n) !gt)
220+ $(points r.points)
221+ =? agg =(targ (end (add 2 (xeb (met 3 targ))) n))
222+ $(points r.points)
223+ =/ should-agg
224+ ?& =(targ (^sein:title n))
225+ ?| =(filter %all)
226+ .= =(filter %locked) (is-npoint-locked +.n.points)
227+ ==
228+ ==
229+ =? agg should-agg
230+ (f agg n.points)
231+ $(points l.points)
232+++ get-spawned-points
233+ |= [targ=ship filter=spawned-filter]
234+ =/ nas get-nas
235+ %- (run-spawned-points (list ship) targ nas filter)
236+ |= [agg=(list ship) [spawn=ship *]]
237+ [spawn agg]
238+::
239+++ spa-count
240+ |= targ=ship
241+ %- (run-spawned-points @ud targ get-nas %all)
242+ |= [agg=@ud [spawn=ship *]]
243+ +(agg)
244+::
245+++ search-opoints-patp
246+ |= [=search-text expand-search=?]
247+ ^- (list ship)
248+ =/ search-fulls
249+ ?: expand-search
250+ (search-text-to-fulls search-text)
251+ ~[(search-text-to-full search-text)]
252+ (search-opoints search-fulls)
253+::
254+++ search-opoints-sigil
255+ |= [=search-text]
256+ ^- (list ship)
257+ =/ search-fulls
258+ ~[(sigil-search-text-to-full search-text)]
259+ (search-opoints search-fulls)
260+::
261+++ search-opoints
262+ |= [search-fulls=(list search-full)]
263+ ^- (list ship)
264+ =/ mr-searches (maybe-reverse-searches search-fulls 1.000)
265+ :: ~& (turn mr-searches |=(=mr-search pain.mr-search))
266+ :: ~& mr-searches
267+ ?~ mr-searches ~|(%search-predicted-too-broad !!)
268+ =/ res
269+ %+ roll `(list mr-search)`mr-searches
270+ (run-mr-search fopoints ropoints)
271+ :: ~& "search for {<search-text>}".
272+ :: " returning {<~(wyt by agg.res)>}".
273+ :: " of {<count.res>} results"
274+ (turn ~(tap in agg.res) head)
275+::
276+++ sponsor-chain
277+ |= [=ship =unpoint]
278+ ^- (list ^ship)
279+ ?~ unpoint ~
280+ =/ sponsor sponsor.net.u.unpoint
281+ ?. has.sponsor ~
282+ =/ spon who.sponsor
283+ ?: =(spon ship) ~
284+ :- spon
285+ =/ spon-point (get-unpoint spon)
286+ $(ship spon, unpoint spon-point)
287+::
288+++ probable-dominion
289+ |= [=ship =unpoint]
290+ ^- dominion:naive
291+ ?^ unpoint
292+ dominion.u.unpoint
293+ =/ parent (^sein:title ship)
294+ ?: =(parent ship) %l1
295+ =/ parent-point (get-unpoint parent)
296+ $(ship parent, unpoint parent-point)
297+::
298+++ get-chart-data
299+ ^- json
300+ =/ nas get-nas
301+ =/ main-data
302+ ^- tape
303+ %- ~(rep by spam)
304+ |= [[=ship kids=(map ship tape)] agg=tape]
305+ ^- tape
306+ %+ weld agg
307+ %+ pdata:smel (ship:smel ship)
308+ (flop ~(val by kids))
309+ =/ gal-data
310+ %+ pdata:smel "base"
311+ %+ turn galaxies
312+ |= gal=ship
313+ =/ npoint (get-npoint-from-nas gal nas)
314+ (pdata:smel (pmeta:smel gal npoint) ~)
315+ s+(crip :(weld "[" gal-data main-data "]"))
316+::
317+::
318+++ ug-handler-card
319+ =/ ug-vase !>([/astrolabe '/apps/astrolabe/#'])
320+ [%pass /monkey-ug %agent [our.bowl %monkey] %poke [%bind-ug ug-vase]]
321+++ groups-link-patch-card
322+ =/ catch [%cord '/apps/groups/desk.js']
323+ =/ hatch [%before "."]
324+ =/ patch [/apps/groups catch hatch groups-link-thatch]
325+ =/ patch-kit-vase !>([/groups/astrolabe/link patch])
326+ [%pass /monkey/patch/groups/link %agent [our.bowl %monkey] %poke [%patch patch-kit-vase]]
327+++ talk-link-patch-card
328+ =/ catch [%cord '/apps/talk/desk.js']
329+ =/ hatch [%before "."]
330+ =/ patch [/apps/talk catch hatch groups-link-thatch]
331+ =/ patch-kit-vase !>([/talk/astrolabe/link patch])
332+ [%pass /monkey/patch/talk/link %agent [our.bowl %monkey] %poke [%patch patch-kit-vase]]
333+::
54334++ read-doc
55335 |= =path
56336 =/ doc-path=^path :(weld /doc/usr path /udon)
57337 ^- (unit @t)
58338 ?. .^(? %cu (scrio q.byk.bowl doc-path))
59339 ~
60− =/ mme=(each manx *) (mule |.((udon-to-docu .^(@t %cx (scrio q.byk.bowl doc-path)))))
340+ =/ mme=(each manx tang) (mule |.((udon-to-docu .^(@t %cx (scrio q.byk.bowl doc-path)))))
61341 ?: ?=(%.n -.mme)
342+ %- (slog p.mme)
62343 ~
63344 `(crip (en-xml:html p.mme))
64345--
desk/desk.docket-0+5−4
@@ -1,9 +1,10 @@
11:~ title+'Astrolabe'
2− info+'An Urbit app that does great things'
3− color+0x2e.4347
4− glob-http+['https://bootstrap.urbit.org/glob-0v5.hurm4.ejod5.ngg9h.iub9i.n1j7o.glob' 0v5.hurm4.ejod5.ngg9h.iub9i.n1j7o]
2+ info+'Your guide to the Urbit constellations. Search for ships, view their info, and explore the Star Chart.'
3+ color+0x1f.243c
4+ image+'https://raw.githubusercontent.com/johnhyde/astrolabe/main/ui/src/assets/astrolabe-tile.svg'
5+ glob-http+['https://s3.us-east-2.amazonaws.com/warkgnall.com/urbit/astrolabe/globs/glob-0v4.88rt1.guqn5.nnatp.lca68.ej9aj.glob' 0v4.88rt1.guqn5.nnatp.lca68.ej9aj]
56 base+'astrolabe'
6− version+[0 0 1]
7+ version+[1 0 7]
78 website+'https://github.com/johnhyde/astrolabe'
89 license+'MIT'
910==
desk/desk.sealnew file+7
@@ -0,0 +1,7 @@
1+:- :~ [%watch & %azimuth /event]
2+ [%reads %gall `%x `%azimuth /]
3+ [%reads %clay `%u ~ /]
4+ [%reads %clay `%x ~ /]
5+ [%reads %ames `%x ~ /peers]
6+ ==
7+~
desk/doc.cluedeleted−24
@@ -1,24 +0,0 @@
1−:-
2−:: User docs
3−::
4−:~ [/urbit-id/udon 'What is an Urbit ID?']
5− :: [/bar/udon 'bar docs']
6− :: [/baz/udon 'baz docs']
7−==
8−:: Developer docs
9−::
10−:: :~ :- %$
11−:: :~ [/foo/udon 'Some whole-desk docs']
12−:: [/bar/udon 'More whole-desk docs']
13−:: ==
14−:: :- %my-agent
15−:: :~ [/blah/udon 'blah blah']
16−:: [/etc/udon 'another doc']
17−:: ==
18−:: :- %another-agent
19−:: :~ [/foo/udon 'Foo title']
20−:: [/bar/udon 'Bar title']
21−:: [/baz/udon 'Baz title']
22−:: ==
23−:: ==
24−~
desk/doc.tocnew file+15
@@ -0,0 +1,15 @@
1+/overview/udon Overview
2+/usr User
3+ /urbit-id/udon What is an Urbit ID?
4+ /galaxy/udon Galaxies
5+ /star/udon Stars
6+ /planet/udon Planets
7+ /moon/udon Moons
8+ /comet/udon Comets
9+ /patpee/udon What is a @p?
10+ /phonemes/udon Phonemes - Prefixes & Suffixes
11+ /sigil/udon What is a Sigil?
12+ /azimuth/udon What is Azimuth?
13+ /l2/udon Layer 1 and Layer 2
14+ /keys/udon Networking Keys
15+ /astrolabe/udon About Astrolabe
desk/doc/overview.udonnew file+26
@@ -0,0 +1,26 @@
1+;>
2+# Astrolabe
3+
4+Currently Astrolabe lets you input `@p`s, Azimuth point numbers, or sigils
5+to look up ships on the network. Use the Star Chart to explore visually.
6+There's also Help Documentation if you want to learn more about how Urbit IDs work.
7+
8+[How to Use Astrolabe](/~/scry/docs/usr/astrolabe/astrolabe.html)
9+
10+## Info
11+
12+- Developer: ~midlev-mindyr
13+- License: MIT
14+- App link: [~dister-midlev-mindyr/astrolabe](web+urbitgraph://~dister-midlev-mindyr/astrolabe)
15+- Source repo: [https://github.com/johnhyde/astrolabe](https://github.com/johnhyde/astrolabe)
16+- Bug reports: [https://github.com/johnhyde/astrolabe/issues](https://github.com/johnhyde/astrolabe/issues)
17+
18+## Feedback
19+
20+If you run into issues with the app, or want to voice comments or concerns,
21+please post in the group `~poster-hoster-midlev-mindyr/astrolabe`, send a DM to `~midlev-mindyr`,
22+or [create an Issue on GitHub](https://github.com/johnhyde/astrolabe/issues).
23+
24+If you see something you want to improve, please fork the [GitHub repository](https://github.com/johnhyde/astrolabe) and make a pull request.
25+
26+Thanks for using Astrolabe. I hope it serves you well.
desk/doc/usr/astrolabe.udonnew file+107
@@ -0,0 +1,107 @@
1+;>
2+# Astrolabe
3+
4+Astrolabe is your one-stop shop for exploring Urbit address space.
5+Currently, Astrolabe lets you type in `@p`s or Azimuth point numbers
6+to look up ships on the network. You can search your contacts and
7+spawned ships with partial or wildcard searches, e.g. `sampel-***net`.
8+
9+There's also Help Documentation if
10+you want to learn more about how Urbit IDs work.
11+
12+## Keyboard Shortcuts
13+
14+- `/` - focus the search bar
15+- `escape` - leave text fields, close help pages, etc
16+- `?` - open the help docs
17+- `s` - switch to sigil search
18+- `p` - switch to patp search
19+- `backspace` or `x` - clear sigil input info
20+
21+
22+## How to Use Search
23+
24+When you type part of a `@p` into the search bar, all your contacts and peers will be
25+searched for IDs matching that string. You can use an asterisk (`*`) to
26+stand in for any character. If you wanted to search for both `~samnec` and `~sarbec`,
27+you could type `~sa**ec`.
28+Contacts are listed before other ships, with a gold border on the left.
29+
30+You can exclude moons or include comets you've met with the toggles in the gold
31+settings box under the search bar.
32+
33+The records of all spawned ships will also be searched, but if the search is
34+too general it will be narrowed in scope, or not run at all. For example,
35+if you search for `***hec`, it will search for all stars under `~hec`,
36+and all planets that match `~***hec-******`, but planets matching `~******-***hec`
37+will be ignored to prevent the search from taking too long.
38+
39+## Sigil Search
40+
41+Clicking the symbol at the right of the search bar opens the Sigil Input Tool.
42+Use the dropdown at the top to select Galaxy, Star, or Planet.
43+Click on a square to start selecting sigil components.
44+
45+Select component categories on the right, and then click the options on the sigil
46+to add them to your search.
47+
48+The ^ button goes up a level so you can select another category.
49+The X button will clear sigil components from the current symbol,
50+except the basic shape. If only the basic shape remains, the X button will clear that.
51+At the top level, the X button will clear all inputs.
52+
53+Your contacts will be searched for any input.
54+When the search has become specific enough,
55+all spawned ships with matching sigils will be shown.
56+If your input is unambiguous, the page for the matching ship will be shown,
57+whether the ship is spawned or not.
58+
59+NOTE: Some sigil inputs are considered ambiguous, even if they exactly match
60+a particular sigil, because further details could match a different sigil.
61+E.g. `~zod` is a circle, but a circle in the suffix position might be intended as a more general search.
62+A future version of Astrolabe will allow you to view the ship
63+whose sigil most closely matches your search, even if the search is ambiguous.
64+
65+Read more about Sigils [here](/~/scry/docs/usr/astrolabe/sigil.html).
66+
67+## The Star Chart
68+
69+Click and drag to move your view; use the mouse wheel to zoom in and out. Click on a dot
70+to see the full Ship View. Enter full `@p`s in the search bar to find a specific point.
71+
72+Please note that stars [locked in the Linear Release Contract](/~/scry/docs/usr/astrolabe/star.html)
73+are not shown in the Star Chart, as they are not yet a part of the network (though they've technically
74+been spawned).
75+
76+The Sponsors/Parents toggle lets you switch between two different views of the network.
77+The default Sponsors view shows each planet under its sponsoring star and each
78+star under its sponsoring galaxy. Planets and Stars without sponsors are not
79+present in this view.
80+The Parent view simply shows each point under the point that spawned it. All spawned points
81+are shown in this view, with the exception of locked stars.
82+In both views, all galaxies are shown for completeness.
83+
84+The All/Peers/Pals selector lets you filter which points are easily visible in the graph.
85+If you select Peers, only those ships that your ship has talked to will be full-colored.
86+If you select Pals, only ships you've added in `%pals` will be full-colored.
87+
88+## Info
89+
90+- Developer: ~midlev-mindyr
91+- License: MIT
92+- App link: [~dister-midlev-mindyr/astrolabe](web+urbitgraph://~dister-midlev-mindyr/astrolabe)
93+- Discussion Group: [~poster-hoster-midlev-mindyr/astrolabe](web+urbitgraph://group/~poster-hoster-midlev-mindyr/astrolabe)
94+- [%quorum](web+urbitgraph://~dister-dister-sidnym-ladrut/quorum) board: ~poster-hoster-midlev-mindyr/astrolabe
95+- Grant/Proposal: [https://urbit.org/grants/astrolabe](https://urbit.org/grants/astrolabe)
96+- Source repo: [https://github.com/johnhyde/astrolabe](https://github.com/johnhyde/astrolabe)
97+- Bug reports: [https://github.com/johnhyde/astrolabe/issues](https://github.com/johnhyde/astrolabe/issues)
98+
99+## Feedback
100+
101+If you run into issues with the app, or want to voice comments or concerns,
102+please post in the group `~poster-hoster-midlev-mindyr/astrolabe`, send a DM to `~midlev-mindyr`,
103+or [create an Issue on GitHub](https://github.com/johnhyde/astrolabe/issues).
104+
105+If you see something you want to improve, please fork the [GitHub repository](https://github.com/johnhyde/astrolabe) and make a pull request.
106+
107+Thanks for using Astrolabe. I hope it serves you well.
desk/doc/usr/azimuth.udonnew file+51
@@ -0,0 +1,51 @@
1+;>
2+# Azimuth
3+
4+_Adapted from [the Glossary](https://urbit.org/docs/glossary/azimuth)_
5+
6+Azimuth is Urbit's identity layer, built as a suite of smart contracts on
7+the Ethereum blockchain and several apps running locally on your
8+[ship](/~/scry/docs/usr/astrolabe/urbit-id.html).
9+It is Urbit's method of securing the digital identities that are required to use
10+the [Arvo](https://urbit.org/docs/glossary/arvo) peer-to-peer network,
11+without the need for a central authority.
12+Azimuth identities (also called points) exist as non-fungible tokens (NFTs),
13+which are owned by Ethereum addresses and can be transferred between such addresses.
14+Identities can use the [claims](https://urbit.org/docs/glossary/claims)
15+contract to make assertions – real-world or otherwise – about their owner.
16+
17+The primary way to interact with Azimuth and to manage your (also called points)
18+is through the [Bridge](https://bridge.urbit.org/) application.
19+Bridge is a front-end for [Ecliptic](https://urbit.org/docs/glossary/ecliptic),
20+the Azimuth contract that's used to perform actions on the blockchain.
21+
22+There are a limited number of Azimuth identities, which results in identities having value.
23+Users are therefore more careful to maintain a good reputation,
24+rather than using identities disposably.
25+Undesirable behavior—spamming, scamming, and malware-spreading—will generally result in
26+a [censure](https://urbit.org/docs/glossary/censure)
27+from [galaxies](/~/scry/docs/usr/astrolabe/galaxy.html)
28+and [stars](/~/scry/docs/usr/astrolabe/star.html), marking the bad actor.
29+
30+It should be noted that Azimuth isn't built just for Arvo.
31+It can be used as an identity system for other projects.
32+
33+## Layer 1 and Layer 2
34+
35+All Azimuth transactions that happen directly on Ethereum (the default) are considered to
36+be on "Layer 1", or L1 for short.
37+However, Ethereum gas prices can make simple L1 transactions like spawning a planet very
38+expensive.
39+In 2021, Tlon developed a "Layer 2" solution (a.k.a. L2) whereby many transactions can be
40+"rolled up" and posted to Ethereum at once, to be validated by each Urbit ship.
41+This dramatically reduces gas costs, and Tlon provides a roller which is free for public use.
42+
43+[Read More about L1 and L2](/~/scry/docs/usr/astrolabe/l2.html)
44+
45+## Further Reading
46+
47+- [The Azimuth concepts page](https://urbit.org/docs/azimuth/azimuth):
48+ A more in-depth explanation of Azimuth.
49+- [Install instructions](https://urbit.org/getting-started/):
50+ Guide to installing Urbit, which includes instructions on booting with your Urbit identity.
51+- [Understanding Urbit ID](https://urbit.org/understanding-urbit/urbit-id)
desk/doc/usr/comet.udonnew file+10
@@ -0,0 +1,10 @@
1+;>
2+[< What is an Urbit ID?](/~/scry/docs/usr/astrolabe/urbit-id.html)
3+
4+# Comets
5+
6+Comets are essentially unlimited, and can be created for free by anyone.
7+They're good for new people exploring the network, operating somewhat anonymously,
8+and testing things out. However, the keys for a comet can't be changed, so it's not
9+not a viable long-term ID. Also, since anyone can boot a comet, comets might be viewed
10+with distrust in some contexts.
desk/doc/usr/galaxy.udonnew file+36
@@ -0,0 +1,36 @@
1+;>
2+[< What is an Urbit ID?](/~/scry/docs/usr/astrolabe/urbit-id.html)
3+
4+# Galaxies
5+
6+Galaxies are the rarest and highest ranking class of Urbit ID, as there are only 256 of them.
7+Together, they form the [Galactic Senate](https://urbit.org/docs/glossary/senate)
8+which has the power make changes to the Urbit ID system.
9+Galaxies help route communication on the network, and each one can spawn 255 [stars](/~/scry/docs/usr/astrolabe/star.html).
10+
11+## @p
12+
13+A galaxy `@p` is just one phoneme, 3 letters. E.g. `~zod`, `~bus`, and `~fes` are galaxies.
14+
15+## Spawning
16+
17+Each galaxy can spawn 255 stars.
18+These stars will have 2-phoneme `@p`s starting with a prefix, and ending with the galaxy's `@p`.
19+E.g. `~zod` spawned `~marzod`, `~binzod`, and `~wanzod`, among others.
20+
21+## Sponsoring
22+
23+A galaxy can sponsor stars and planets, although usually planets are sponsored by stars.
24+By default, a galaxy will sponsor all its children, although it can sponsor others as well.
25+
26+Galaxies perform peer discovery for their sponsees, meaning that they tell other Urbit IDs
27+where they can find their sponsees so that they can communicate directly withthem—similar to
28+asking a DNS server to tell you where to look for google.com.
29+Thus, it is crucially important that galaxies be online and reachable.
30+
31+## The Galactic Senate
32+
33+All galaxy owners are members of the [Galactic Senate](https://urbit.org/docs/glossary/senate).
34+Galaxy owners can [vote](https://urbit.org/docs/glossary/voting) on proposals
35+to upgrade the logic of [Azimuth](/~/scry/docs/usr/astrolabe/azimuth.html)
36+or approve the content of a document.
desk/doc/usr/keys.udonnew file+63
@@ -0,0 +1,63 @@
1+;>
2+# Networking Keys
3+
4+Each Urbit ship proves its identity on the network by signing its messages
5+with a pair of networking keys. By signing a message with a private key,
6+you prove that you are the owner of the associated public key.
7+
8+Since public keys are stored in [Azimuth](/~/scry/docs/usr/astrolabe/azimuth.html),
9+other ships can verify your identity by checking your signatures.
10+
11+## Keyfile
12+
13+A keyfile is just a file containing your networking keys. It is used when
14+booting Arvo (Urbit's OS) for the first time, and the information within
15+is baked into the resulting ship. After this, the keyfile should be deleted
16+to prevent accidentally double-booting in the future.
17+
18+## Changing Keys
19+
20+If your private key is compromised, you can change your keys in Bridge and
21+update your ship by running `|rekey 'new-private-key-goes-here'` in Dojo (the terminal).
22+This will increase your `life` number in Azimuth, which is just a record of how many
23+times your keys have been revised. This number will also be incremented if you
24+set new keys in the course of performing a factory reset.
25+
26+Since keys must be set before a ship can be booted,
27+all active Urbit IDs will have a `life` of at least 1.
28+
29+# Performing a Factory Reset (a.k.a. Breaching)
30+
31+When using the network, ships keep track of the order of all the messages they've sent
32+and received, and use this to ensure that they process messages properly.
33+This is called continuity.
34+
35+Performing a factory reset means breaking continuity—asking the rest of the network
36+to forget your past messages and treat you like a new ship. It also involves clearing
37+your own event log, and consequently all apps and data on the ship.
38+Sometimes this is done to resolve networking errors, like those caused by double-booting.
39+This is also appropriate when transferring an ID to someone else, to give them a fresh start.
40+
41+Because factory resets involve booting a fresh ship, you'll need to rejoin groups,
42+reinstall apps, and generally start from scratch. Trying to continue using your old pier
43+(the folder containing your data) will just cause more networking issues.
44+There are, however, a few unofficial tools with which you can restore some data from
45+a previous pier, and more will likely be built over time.
46+
47+If you want to avoid breaching, avoid double-booting and don't delete your pier.
48+If you want to move your pier (e.g. to host your ship on a remote server), it is
49+crucial that you shut down your ship before you start it somewhere else.
50+If you have two different instances of the same ship trying to run at the same time,
51+other ships will get confused and you will need to breach to communicate with them properly.
52+Deleting your pier, or using an outdated archive of your pier will have the same effect.
53+
54+Breaching, or performing a factory reset, will increment your `rift` number in Azimuth,
55+so this number is an indicator of how many times a ship has breached.
56+Ships which have never breached have a `rift` of 0.
57+
58+# Further Reading
59+
60+- [Setting initial networking keys](https://urbit.org/using/id/using-bridge#set-your-networking-keys)
61+- [Guide to Factory Resets](https://urbit.org/using/id/guide-to-resets)
62+- [Life and Rift](https://urbit.org/docs/azimuth/life-and-rift)
63+- [Glossary: Keyfile](https://urbit.org/docs/glossary/keyfile)
desk/doc/usr/l2.udonnew file+60
@@ -0,0 +1,60 @@
1+;>
2+# What are Layer 1 and Layer 2?
3+
4+## Layer 1 (L1) - Azimuth smart contracts
5+
6+All Azimuth transactions that happen directly on Ethereum (the default) are considered to
7+be on "Layer 1", or L1 for short. The effects of these transactions are calculated and
8+stored on the Ethereum blockchain, so a nontrivial amount of "gas" must be expended for
9+each L1 transaction.
10+
11+## The need for a workaround
12+
13+In 2021, the Ethereum blockchain saw a large increase in traffic which caused
14+gas prices to skyrocket. It became prohibitively expensive for many to spawn or set keys
15+for new IDs, so Tlon started developing a workaround.
16+
17+## Layer 2 (L2) - Naive Rollups
18+
19+Tlon developed a "Layer 2" solution (a.k.a. L2) whereby many transactions can be
20+"rolled up" and posted to Ethereum at once, to be validated by each Urbit ship.
21+
22+The technical term for this is "naive rollups" because transactions are combined and
23+posted to Ethereum without being validated.
24+Each Urbit ship validates the transactions locally to determine who actually owns what.
25+
26+Combining transactions and offloading computation
27+from Ethereum to Urbit dramatically reduces gas costs.
28+Using L2 is so cheap that Tlon provides a free "roller" which is used when performing
29+L2 actions through Bridge.
30+
31+The introduction of L2 also makes it possible for new users to receive and start using
32+Urbit IDs without ever interacting with the blockchain themselves, making Urbit generally
33+more accessible.
34+
35+### Moving to Layer 2
36+
37+Most L2 actions require the ship to first "move to L2", which can be done through Bridge.
38+Technically, this consists of transferring the ID to `0x1111111111111111111111111111111111111111`.
39+This tells the Layer 2 code that the ship is on L2.
40+After that, all Azimuth transactions will be done on L2. It is not possible to move
41+an L2 ship back to L1.
42+
43+For galaxies and stars that want to spawn new IDs on L2, they can move only their spawn proxy
44+to L2. They will remain on L1, but any new children will be on L2. This change is also irreversible.
45+
46+Galaxies cannot move fully to L2, but they can move their spawn proxy to L2. Note, however, that
47+any stars locked in the Linear Release Contract are technically already spawned on L1,
48+and would need to be transferred to L2 separately.
49+
50+### Sponsorship between L1 and L2
51+
52+A sponsor and its sponsee can live on separate layers, but unless they are both on L1,
53+most sponsorship actions will need to take place on L2. This is the situation where an L1 ID
54+can take actions on L2 without moving to L2.
55+
56+# Further Reading
57+
58+- [Technical Overview of L2](https://urbit.org/docs/azimuth/l2/layer2)
59+- [Blog on Naive Rollups](https://urbit.org/blog/rollups)
60+- [Technical Details about which ships can perform which L2 actions](https://urbit.org/docs/azimuth/l2/l2-actions)
desk/doc/usr/moon.udonnew file+8
@@ -0,0 +1,8 @@
1+;>
2+[< What is an Urbit ID?](/~/scry/docs/usr/astrolabe/urbit-id.html)
3+
4+# Moons
5+
6+Moons are created, owned, and controlled by a parent ID, either a galaxy, star, or planet.
7+Moons are free and easy to create, and each Azimuth point can create about 4 billion.
8+Moons can use the Urbit network just like any other ID, but they are inextricably linked to their parents.
desk/doc/usr/patpee.udonnew file+104
@@ -0,0 +1,104 @@
1+;>
2+# What is a @p?
3+
4+First of all, it's pronounced "pat-pee", and we'll see why later.
5+
6+## It's a name
7+
8+Your `@p` is your name on Urbit, and it's designed to be pronounceable.
9+A `@p` starts with a tilde (`~`), and is made up of 3-letter phonemes/syllables, a combination of prefixes and suffixes.
10+There are 256 prefixes, and 256 suffixes.
11+`~zod` and `~bus` are galaxies, so their whole `@p`s are just one suffix.
12+
13+Most `@p`s are made up of 6-letter "words" ( a prefix + a suffix), joined by hyphens.
14+E.g. `~midlev-mindyr` has the prefixes `mid` and `min` and the suffixes `lev` and `dyr`.
15+You can see a list of prefixes and suffixes [here](/~/scry/docs/usr/astrolabe/phonemes.html).
16+
17+## It's a number
18+
19+A `@p` is actually just a way to write a non-negative integer with phonemes.
20+That means every `@p` can be written as a number, and any non-negative integer can be written as a `@p`.
21+- `~zod` is 0 (the first galaxy)
22+- `~marzod` is 256 (the first star)
23+- `~dapnep-ronmyl` is 65536 (256², the first planet)
24+- `~sampel-palnet` is 1624961343.
25+- `~doznec-dozzod-dozzod` is 4294967296 (256⁴, the first moon, moon of `~zod`)
26+
27+For [Azimuth points](/~/scry/docs/usr/astrolabe/azimuth.html), this number is also
28+called the Azimuth number, and it's stored on the blockchain instead of a `@p`.
29+The highest Azimuth number is 256⁴ - 1 (4294967295).
30+Everything above that is a moon, a comet, or not a valid ID number.
31+
32+## It's a username / email address / phone number
33+
34+A `@p` is the unique identifier for a ship, and it's used all throughout Urbit, in the code and in user-facing apps.
35+A `@p` can't be changed.
36+It will always refer to the same Urbit ID, and that Urbit ID will always have the same `@p`.
37+A given ID may change owners, however, and you can always buy a new ID with a new `@p`.
38+
39+## How to tell a ship's class
40+
41+It's easy to tell the class of a ship by looking at its `@p`.
42+- If it's just 1 phoneme, a suffix, like `~zod` or `~bus`, it's a [galaxy](/~/scry/docs/usr/astrolabe/galaxy.html).
43+
44+- If it has 2 phonemes, a prefix and a suffix, like `~marzod` or `~batbus`, it's a [star](/~/scry/docs/usr/astrolabe/star.html).
45+
46+ The suffix of a star `@p` is its parent galaxy, so the parent of `~marzod` is `~zod`, and the parent of `~batbus` is `~bus`.
47+
48+- If it has 4 phonemes separated by a hyphen, like `~sampel-palnet`, it's a [planet](/~/scry/docs/usr/astrolabe/planet.html).
49+
50+ Unlike stars, planet `@p`s don't contain the `@p` of their parent—the names are scrambled
51+ to give each star a good variety of planet `@p`s to spawn.
52+
53+- If it has 8 phonemes, like `~poster-hoster-midlev-mindyr`, it's a [moon](/~/scry/docs/usr/astrolabe/moon.html).
54+
55+ If it has 4 phonemes separated by a caret, like `~midlev^mindyr`, that's an abbreviated moon `@p`.
56+ The last 4 phonemes of a moon `@p` give its parent, and are used in the abbreviation.
57+
58+- If it has 16 phonemes, like `~dirbec-morfeb-ritlys-timsef--padnum-mapnep-nolfel-binzod`,
59+ or more likely 4 phonemes separated by an underscore, like `~dirbec_binzod`,
60+ it's a [comet](/~/scry/docs/usr/astrolabe/comet.html).
61+
62+ You may notice a double hyphen in the center of the full comet `@p`.
63+ This is part of the required syntax of a `@p`, and makes it easier to read.
64+ The abbreviation combines the first and last "words" of the `@p` with an underscore.
65+
66+
67+## The thing about `doz` and `zod`
68+
69+Remember that a `@p` is actually just a way of writing a number.
70+Technically, a `@p` is a base-256 number, as it's composed of prefixes and suffixes,
71+and there are 256 of each. Sure, you could write a number with just prefixes, or just suffixes,
72+but it wouldn't be as interesting to read, and it wouldn't be a valid `@p`.
73+
74+So each phoneme is equivalent to a number, 0-255.
75+`doz` is the prefix version of 0, and `zod` is the suffix version of 0.
76+Just as we usually don't write leading zeroes in our numbers, we omit the equivalent
77+of leading zeroes in `@p`s.
78+This is why you will never see `~dozler`, or `~dozzod-palnet`. It would be sort of like writing `000218` or `0000032591`. It's just `~ler` and `~palnet`. You might, however, run into `~dozler-palnet`, as planet `@p`s are never shortened to 3 phonemes.
79+
80+One place you're likely to see these show up is in moon `@p`s.
81+A moon `@p` is one or two "words" of the parent's choosing, plus the parent's `@p`.
82+E.g. `~sampel-palnet` could create `~dister-sampel-palnet` or `~mister-master-sampel-palnet`,
83+among others.
84+
85+If a galaxy or a star creates a moon,
86+its `@p` must be "padded out" to make up the last 4 phonemes of the moon `@p`.
87+`~ler` could thus create `~faster-dozzod-dozler` or `~poster-hoster-dozzod-dozler`.
88+See how `doz` and `zod` were used to pad out `ler` to 4 phonemes?
89+Similarly, `~palnet` could create `~walrus-dozzod-palnet` or `~doznec-tortul-dozzod-palnet`.
90+
91+## Why is it called a "patpee"?
92+
93+In Hoon, Urbit's typed programming language, numbers can have different "auras",
94+depending on what they represent. Some auras include `@u` for an unsigned integer,
95+`@t` for arbitrary text stored as a number, `@if` for an IPv4 address, and of course
96+`@p` for writing a number in phonemes.
97+
98+So why the "pat"?
99+Hoon involves a lot more symbols than most programming languages (e.g. `.!=?|+:%^$;~-` and so on).
100+To help programmers talk out loud about Hoon, each symbol is associated with a 3-letter phoneme.
101+In this system, `=/` is pronounced "tisfas", `%-` is "cenhep", and, you guessed it, `@` is "pat".
102+
103+In short, `@p` is originally a programming term, the programmers pronounce it "pat-pee",
104+so that's how it's pronounced.
desk/doc/usr/phonemes.udonnew file+45
@@ -0,0 +1,45 @@
1+;>
2+# Phonemes - Prefixes & Suffixes
3+
4+[< What is a @p?](/~/scry/docs/usr/astrolabe/patpee.html)
5+
6+`@p`s are made up of 3-letter phonemes, a mixture of prefixes and suffixes.
7+Here's an exhaustive list of each:
8+
9+## Prefixes
10+
11+`doz` `mar` `bin` `wan` `sam` `lit` `sig` `hid` `fid` `lis` `sog` `dir` `wac` `sab` `wis` `sib`
12+`rig` `sol` `dop` `mod` `fog` `lid` `hop` `dar` `dor` `lor` `hod` `fol` `rin` `tog` `sil` `mir`
13+`hol` `pas` `lac` `rov` `liv` `dal` `sat` `lib` `tab` `han` `tic` `pid` `tor` `bol` `fos` `dot`
14+`los` `dil` `for` `pil` `ram` `tir` `win` `tad` `bic` `dif` `roc` `wid` `bis` `das` `mid` `lop`
15+`ril` `nar` `dap` `mol` `san` `loc` `nov` `sit` `nid` `tip` `sic` `rop` `wit` `nat` `pan` `min`
16+`rit` `pod` `mot` `tam` `tol` `sav` `pos` `nap` `nop` `som` `fin` `fon` `ban` `mor` `wor` `sip`
17+`ron` `nor` `bot` `wic` `soc` `wat` `dol` `mag` `pic` `dav` `bid` `bal` `tim` `tas` `mal` `lig`
18+`siv` `tag` `pad` `sal` `div` `dac` `tan` `sid` `fab` `tar` `mon` `ran` `nis` `wol` `mis` `pal`
19+`las` `dis` `map` `rab` `tob` `rol` `lat` `lon` `nod` `nav` `fig` `nom` `nib` `pag` `sop` `ral`
20+`bil` `had` `doc` `rid` `moc` `pac` `rav` `rip` `fal` `tod` `til` `tin` `hap` `mic` `fan` `pat`
21+`tac` `lab` `mog` `sim` `son` `pin` `lom` `ric` `tap` `fir` `has` `bos` `bat` `poc` `hac` `tid`
22+`hav` `sap` `lin` `dib` `hos` `dab` `bit` `bar` `rac` `par` `lod` `dos` `bor` `toc` `hil` `mac`
23+`tom` `dig` `fil` `fas` `mit` `hob` `har` `mig` `hin` `rad` `mas` `hal` `rag` `lag` `fad` `top`
24+`mop` `hab` `nil` `nos` `mil` `fop` `fam` `dat` `nol` `din` `hat` `nac` `ris` `fot` `rib` `hoc`
25+`nim` `lar` `fit` `wal` `rap` `sar` `nal` `mos` `lan` `don` `dan` `lad` `dov` `riv` `bac` `pol`
26+`lap` `tal` `pit` `nam` `bon` `ros` `ton` `fod` `pon` `sov` `noc` `sor` `lav` `mat` `mip` `fip`
27+
28+## Suffixes
29+
30+`zod` `nec` `bud` `wes` `sev` `per` `sut` `let` `ful` `pen` `syt` `dur` `wep` `ser` `wyl` `sun`
31+`ryp` `syx` `dyr` `nup` `heb` `peg` `lup` `dep` `dys` `put` `lug` `hec` `ryt` `tyv` `syd` `nex`
32+`lun` `mep` `lut` `sep` `pes` `del` `sul` `ped` `tem` `led` `tul` `met` `wen` `byn` `hex` `feb`
33+`pyl` `dul` `het` `mev` `rut` `tyl` `wyd` `tep` `bes` `dex` `sef` `wyc` `bur` `der` `nep` `pur`
34+`rys` `reb` `den` `nut` `sub` `pet` `rul` `syn` `reg` `tyd` `sup` `sem` `wyn` `rec` `meg` `net`
35+`sec` `mul` `nym` `tev` `web` `sum` `mut` `nyx` `rex` `teb` `fus` `hep` `ben` `mus` `wyx` `sym`
36+`sel` `ruc` `dec` `wex` `syr` `wet` `dyl` `myn` `mes` `det` `bet` `bel` `tux` `tug` `myr` `pel`
37+`syp` `ter` `meb` `set` `dut` `deg` `tex` `sur` `fel` `tud` `nux` `rux` `ren` `wyt` `nub` `med`
38+`lyt` `dus` `neb` `rum` `tyn` `seg` `lyx` `pun` `res` `red` `fun` `rev` `ref` `mec` `ted` `rus`
39+`bex` `leb` `dux` `ryn` `num` `pyx` `ryg` `ryx` `fep` `tyr` `tus` `tyc` `leg` `nem` `fer` `mer`
40+`ten` `lus` `nus` `syl` `tec` `mex` `pub` `rym` `tuc` `fyl` `lep` `deb` `ber` `mug` `hut` `tun`
41+`byl` `sud` `pem` `dev` `lur` `def` `bus` `bep` `run` `mel` `pex` `dyt` `byt` `typ` `lev` `myl`
42+`wed` `duc` `fur` `fex` `nul` `luc` `len` `ner` `lex` `rup` `ned` `lec` `ryd` `lyd` `fen` `wel`
43+`nyd` `hus` `rel` `rud` `nes` `hes` `fet` `des` `ret` `dun` `ler` `nyr` `seb` `hul` `ryl` `lud`
44+`rem` `lys` `fyn` `wer` `ryc` `sug` `nys` `nyl` `lyn` `dyn` `dem` `lux` `fed` `sed` `bec` `mun`
45+`lyr` `tes` `mud` `nyt` `byr` `sen` `weg` `fyr` `mur` `tel` `rep` `teg` `pec` `nel` `nev` `fes`
desk/doc/usr/planet.udonnew file+9
@@ -0,0 +1,9 @@
1+;>
2+[< What is an Urbit ID?](/~/scry/docs/usr/astrolabe/urbit-id.html)
3+
4+# Planets
5+
6+There are about 4.3 billion potential planets, so while they are not unlimited, they are
7+widely accessible for the average user. Most people pilot a planet or a moon when using Urbit.
8+As planets are the lowest rank of Azimuth point, they cannot spawn other points. Like galaxies
9+and stars, however, they can create [moons](/~/scry/docs/usr/astrolabe/moon.html).
desk/doc/usr/sigil-input.udonnew file+27
@@ -0,0 +1,27 @@
1+;>
2+# How to Search by Sigil
3+
4+Use the dropdown at the top to select Galaxy, Star, or Planet.
5+Click on an empty square to start selecting sigil components.
6+
7+Select component categories on the right, and then click the options on the sigil
8+to add them to your search.
9+
10+The ^ button goes up a level so you can select another category.
11+The X button will clear sigil components from the current symbol,
12+except the basic shape. If only the basic shape remains, the X button will clear that.
13+At the top level, the X button will clear all inputs.
14+
15+Your contacts will be searched for any input.
16+When the search has become specific enough,
17+all spawned ships with matching sigils will be shown.
18+If your input is unambiguous, the page for the matching ship will be shown,
19+whether the ship is spawned or not.
20+
21+_NOTE:_ Some sigil inputs are considered ambiguous, even if they exactly match
22+a particular sigil, because further details could match a different sigil.
23+E.g. `~zod` is a circle, but a circle in the suffix position might be intended as a more general search.
24+A future version of Astrolabe will allow you to view the ship
25+whose sigil most closely matches your search, even if the search is ambiguous.
26+
27+_See Also:_ [*What is a Sigil?*](/~/scry/docs/usr/astrolabe/sigil.html)
desk/doc/usr/sigil.udonnew file+22
@@ -0,0 +1,22 @@
1+;>
2+# What is a Sigil?
3+
4+It's a default profile picture, based on your [`@p`](/~/scry/docs/usr/astrolabe/patpee.html).
5+Each 3-letter syllable corresponds to a sigil shape, or "symbol".
6+Since planet `@p`s have 4 syllables, a planet sigil is a 2x2 grid of 4 symbols.
7+Star sigils have 2 symbols, and galaxies have just 1.
8+
9+![planet sigils](/apps/astrolabe/sigil-example.png)
10+
11+## Is there a pattern to the sigil shapes?
12+
13+Some syllables which sound similar have similar symbols,
14+but there's no real system to it. The sigil shapes were manually selected and assigned,
15+with a focus on visual design rather than algorithmic purity.
16+
17+## Where did they come from?
18+
19+Tlon saw that Urbit IDs need a visual representation,
20+so they designed a system for generating default avatars.
21+You can read about it in the blog post [_Creating Sigils_](https://urbit.org/blog/creating-sigils).
22+
desk/doc/usr/star.udonnew file+21
@@ -0,0 +1,21 @@
1+;>
2+[< What is an Urbit ID?](/~/scry/docs/usr/astrolabe/urbit-id.html)
3+
4+# Stars
5+
6+Stars are scarce and valuable—a natural fit for businesses, communities, or other organizations.
7+The maximum supply of stars is 65,280.
8+
9+Each star can spawn 65,535 [planets](/~/scry/docs/usr/astrolabe/planet.html), and provides network routing, software updates,
10+and other services for the planets it sponsors.
11+Stars can also choose to de-sponsor planets which abuse the network.
12+
13+Stars are NFTs, but they can be exchanged 1:1 for WSTR at [star.market](https://star.market/),
14+and you can trade fractional amounts of WSTR for ETH [on Uniswap V3](https://info.uniswap.org/#/pools/0x7f4a0822a6e3c085df795a8d78acbcd36f210ebf).
15+
16+## Locked stars and the Linear Release Contract
17+
18+To prevent galaxies from spawning too many stars all at once, many galaxies' stars were locked
19+in an Ethereum contract, to be slowly released (at a linear rate) over time.
20+Stars which are locked in this way will show the contract address as their owner,
21+and any stars held by this contract are considered locked, even if they are ready to be released.
desk/doc/usr/urbit-id.udon+116−5
@@ -1,7 +1,118 @@
11;>
2−## What is an Urbit ID
2+# What is an Urbit ID?
33
4−It's pretty cool actually:
5−- secure
6−- unique
7−- fun to say (_sometimes_)
4+An Urbit ID is like an account on the Urbit network. You can’t use Urbit without an Urbit ID.
5+
6+Every active Urbit ID has a number of properties:
7+
8+- `@p` (pronounced pat-pee) - A permanent, unique identifier, e.g. `~zod` or `~midlev-mindyr`.
9+ This often functions like a username or email address.
10+ Every `@p` is equivalent to a number ≥ 0 and > 256¹⁶, with longer `@p`s giving larger numbers.
11+ The length of a `@p` indicates what class of ID it is.
12+ [Read More](/~/scry/docs/usr/astrolabe/patpee.html)
13+
14+- Public and Private Keys - These allow you to cryptographically prove your ownership of an ID.
15+ This is a bit like having a password for an account, or signing a document.
16+ All messages on Urbit are automatically signed and verified, so you know they’re authentic.
17+
18+- Ship - A ship is an Urbit computer, which is always tied to the Urbit ID it was booted with.
19+ When you boot Urbit for the first time, you provide your keys and we call this booting a “ship”.
20+ When you use this computer on the network, you are “piloting” your “ship”.
21+ Your ship stores all your data and apps.
22+
23+## Azimuth Points
24+
25+An [Azimuth point](/~/scry/docs/usr/astrolabe/azimuth.html) is an Urbit ID which is secured on the Ethereum blockchain.
26+Azimuth points are NFTs, governed by the Azimuth smart contracts.
27+Owning an Azimuth point lets you reset your [keys](/~/scry/docs/usr/astrolabe/keys.html),
28+spawn new IDs, and transfer ownership to someone else, among other things.
29+
30+When Ethereum got popular and transactions became very expensive a
31+[Layer 2 solution](/~/scry/docs/usr/astrolabe/l2.html)
32+was developed (commonly called "L2"), which allows Azimuth points to be spawned, transferred,
33+etc. basically for free.
34+
35+### Spawning and Sponsoring
36+
37+By thinking about possible combinations of syllables, we can predict every Urbit ID that might exist.
38+But galaxies, stars, and planets, being Azimuth points, don't come into existence until
39+a transaction is posted to Azimuth which explicitly "spawns" that point.
40+
41+All 256 galaxies have already been spawned. Those galaxies can spawn stars.
42+Those stars can spawn planets. Planets can't spawn anything, but all Azimuth points can
43+create moons, which is sometimes called "spawning" even though it's not done through Azimuth.
44+
45+By default, a galaxy will sponsor any stars it spawns, and a star will sponsor any planets it spawns.
46+This means helping route network traffic between the sponsee and other ships, providing OTA (over the air)
47+software updates, and potentially providing other services.
48+
49+A sponsee (star or planet) may choose to leave their sponsor and find another one. Conversely,
50+a sponsor (galaxy or star) may choose to de-sponsor their sponsee or sponsor additional points
51+which they didn't spawn. This lets the network hierarchy adjust itself in case someone misbehaves.
52+
53+## Classes of Urbit ID
54+
55+There are 5 classes of Urbit ID:
56+[Galaxy](/~/scry/docs/usr/astrolabe/galaxy.html),
57+[Star](/~/scry/docs/usr/astrolabe/star.html),
58+[Planet](/~/scry/docs/usr/astrolabe/planet.html),
59+[Moon](/~/scry/docs/usr/astrolabe/moon.html), and
60+[Comet](/~/scry/docs/usr/astrolabe/comet.html).
61+
62+Galaxies, stars, and planets are [Azimuth points](/~/scry/docs/usr/astrolabe/azimuth.html),
63+and are therefore very similar anatomically, although they have different roles.
64+Moons and comets are a bit different.
65+
66+### Galaxies (e.g. `~bus`)
67+
68+Galaxies are the rarest and highest ranking class of ID, as there are only 256 of them.
69+Together, they form the Galactic Senate.
70+Galaxies help route communication on the network, and each one can spawn 255 stars.
71+
72+[Read More](/~/scry/docs/usr/astrolabe/galaxy.html)
73+
74+### Stars (e.g. `~batbus`)
75+
76+Stars are fairly scarce and valuable—a natural fit for businesses, communities, or other organizations.
77+Each star can spawn 65,535 planets, and provides network routing, software updates,
78+and other services for the planets it sponsors.
79+Stars can also choose to de-sponsor planets which abuse the network.
80+Stars are NFTs, but they can be exchanged 1:1 for WSTR at [star.market](https://star.market/),
81+and you can trade fractional amounts of WSTR for ETH [on Uniswap V3](https://info.uniswap.org/#/pools/0x7f4a0822a6e3c085df795a8d78acbcd36f210ebf).
82+
83+[Read More](/~/scry/docs/usr/astrolabe/star.html)
84+
85+### Planets (e.g. `~midlev-mindyr`)
86+
87+There are about 4.3 billion potential planets, so while they are not unlimited, they are
88+widely accessible for the average user. Most people pilot a planet or a moon when using Urbit.
89+As planets are the lowest rank of Azimuth point, they cannot spawn other points. Like galaxies
90+and stars, however, they can create moons.
91+
92+[Read More](/~/scry/docs/usr/astrolabe/planet.html)
93+
94+### Moons (e.g. `~poster-hoster-midlev-mindyr` (`~midlev^mindyr` for short))
95+
96+Moons are created, owned, and controlled by a parent ID, either a galaxy, star, or planet.
97+Moons are free and easy to create, and each Azimuth point can create about 4 billion.
98+Moons can use the Urbit network just like any other ID, but they are inextricably linked to their parents.
99+
100+[Read More](/~/scry/docs/usr/astrolabe/moon.html)
101+
102+### Comets (e.g. `~dirbec-morfeb-ritlys-timsef--padnum-mapnep-nolfel-binzod` (`~dirbec_binzod` for short))
103+
104+Comets are essentially unlimited, and can be created for free by anyone.
105+They're good for new people exploring the network, operating somewhat anonymously,
106+and testing things out. However, the keys for a comet can't be changed, so it's not
107+not a viable long-term ID. Also, since anyone can boot a comet, comets might be viewed
108+with distrust in some contexts.
109+
110+[Read More](/~/scry/docs/usr/astrolabe/comet.html)
111+
112+# Further Reading
113+
114+- [A more technical overview](https://urbit.org/using/id/overview)
115+- From the Operator’s Guide:
116+ [Which ID should I buy?](https://operators.urbit.org/guides/which-id-should-i-buy)
117+- [Azimuth FAQ](https://azimuth.network/#faq)
118+- [Understanding Urbit ID](https://urbit.org/understanding-urbit/urbit-id)
desk/lib/astrolabe.hoon+174−29
@@ -1,7 +1,106 @@
11/- sur=astrolabe
2+/+ azimuth, naive
23=< [sur .]
34=, sur
45|%
6+++ to-q fein:ob
7+++ to-p fynd:ob
8+++ rev-q
9+ |= a=@
10+ (rev 3 4 a)
11+++ switch-words
12+ |= a=@
13+ (rev 4 2 a)
14+++ add-d
15+ |= [a=@ b=@]
16+ (rev-q (add (rev-q a) b))
17+++ sub-d
18+ |= [a=@ b=@]
19+ (rev-q (sub (rev-q a) b))
20+++ rev-f
21+ |* [f=$-([@ @] *) a=@ b=@]
22+ (f (rev-q a) (rev-q b))
23+++ rpor :: reversed parent order
24+ |= [a=@ b=@]
25+ ^- ?
26+ (rev-f lte a b)
27+::
28+++ ors ((on @q @) rpor)
29+++ or-meta ((on @p tape) por:naive)
30+++ bi-meta
31+ =| a=(map * (map))
32+ |@
33+ ++ put
34+ |* [b=* c=* d=*]
35+ %+ ~(put by a) b
36+ %+ put:or-meta
37+ (~(gut by a) b ~)
38+ [c d]
39+ --
40+::
41++$ page-info [size=_100 page=_0]
42+++ fits-on-page
43+ |= [i=@ =page-info]
44+ ^- ?
45+ =, page-info
46+ ?: =(0 size) %.y
47+ =/ page-start (mul size page)
48+ =/ page-end (add page-start size)
49+ &((gte i page-start) (lth i page-end))
50+::
51+++ is-npoint-locked
52+ |= p=npoint
53+ .= linear-star-release:contracts:azimuth
54+ address.owner.own.p
55+::
56+++ split
57+ |* [nedl=(list) hstk=(list)]
58+ |- ^- (list _hstk)
59+ =/ brk (find nedl hstk)
60+ ?~ brk ~[hstk]
61+ =/ next (add u.brk (lent nedl))
62+ :- (scag u.brk hstk)
63+ $(hstk (slag next hstk))
64+::
65+++ smel
66+ |%
67+ ++ ship
68+ |= =^ship
69+ ^- tape
70+ (slag 1 (scow %p ship))
71+ ++ dom
72+ |= =dominion:naive
73+ ?- dominion
74+ %l1 ""
75+ %l2 "t"
76+ %spawn "s"
77+ ==
78+ ++ spo
79+ |= [self=^ship has=? spo=^ship]
80+ ?. has "~"
81+ =/ parent (^sein:title self)
82+ ?: =(spo parent)
83+ ""
84+ :(weld ":" (ship spo) "!" (ship parent))
85+ ++ pmeta
86+ |= [self=^ship point=npoint]
87+ ^- tape
88+ =/ self-str (ship self)
89+ =/ extras (weld (dom dominion.point) (spo self sponsor.net.point))
90+ ?~ extras self-str
91+ :(weld self-str ":" extras)
92+ ++ spa
93+ |= children=(list tape)
94+ =/ chil-str=tape (zing children)
95+ :: =/ chil-str=tape (reel children |=([a=tape b=tape] (weld a b)))
96+ ?~ chil-str ";"
97+ :(weld "[" chil-str "]")
98+ ++ pdata
99+ |= [pmeta=tape children=(list tape)]
100+ ^- tape
101+ (weld pmeta (spa children))
102+ --
103+::
5104++ nu :: parse number as hex
6105 |= jon=json
7106 ?> ?=([%s *] jon)
@@ -10,41 +109,59 @@
10109++ enjs
11110 =, enjs:format
12111 |%
112+ ++ point-set
113+ |= points=(list ^ship)
114+ ^- json
115+ %+ frond %points
116+ :- %a
117+ %+ turn
118+ points
119+ |= who=^ship
120+ (ship who)
13121 ++ point
14− |= =upoint
122+ |= =^point
15123 ^- json
16− ?~ upoint (pairs ~)
17− =* point u.upoint
124+ =* unpoint unpoint.point
125+ =* npoint u.unpoint
18126 %+ frond %point
19− %- pairs :~
20− [%dominion s+dominion.point]
21− :- %own
22− =* own own.point
127+ %- pairs :*
128+ ship+(ship ship.point)
129+ spa-count+(numb spa-count.point)
130+ [%probable-dominion s+probable-dominion.point]
131+ [%sponsor-chain a+(turn sponsor-chain.point ship)]
132+ ?~ unpoint ~
133+ :_ ~
134+ :- %npoint
23135 %- pairs :~
24− owner+(address owner.own)
25− spawn-proxy+(address spawn-proxy.own)
26− management-proxy+(address management-proxy.own)
27− voting-proxy+(address voting-proxy.own)
28− transfer-proxy+(address transfer-proxy.own)
29− ==
30− :- %net
31− =* net net.point
32− %- pairs
33− :~ rift+(numb rift.net)
34− :- %keys
136+ [%dominion s+dominion.npoint]
137+ :- %own
138+ =* own own.npoint
35139 %- pairs :~
36− life+(numb life.keys.net)
37− suite+(numb suite.keys.net)
38− auth+(numb auth.keys.net)
39− crypt+(numb crypt.keys.net)
140+ owner+(address owner.own)
141+ spawn-proxy+(address spawn-proxy.own)
142+ management-proxy+(address management-proxy.own)
143+ voting-proxy+(address voting-proxy.own)
144+ transfer-proxy+(address transfer-proxy.own)
40145 ==
41− :- %sponsor
42− %- pairs :~
43− has+b+has.sponsor.net
44− who+(ship who.sponsor.net)
146+ :- %net
147+ =* net net.npoint
148+ %- pairs
149+ :~ rift+(numb rift.net)
150+ :- %keys
151+ %- pairs :~
152+ life+(numb life.keys.net)
153+ suite+(numb suite.keys.net)
154+ auth+(numb auth.keys.net)
155+ crypt+(numb crypt.keys.net)
156+ ==
157+ :- %sponsor
158+ %- pairs :~
159+ has+b+has.sponsor.net
160+ who+(ship who.sponsor.net)
161+ ==
162+ :- %escape
163+ (biff escape.net ship)
45164 ==
46− :- %escape
47− (biff escape.net ship)
48165 ==
49166 ==
50167 ++ address
@@ -76,7 +193,7 @@
76193 |%
77194 ++ point
78195 |= jon=json
79− ^- upoint ~
196+ *^point
80197 --
81198::
82199++ share-dejs
@@ -86,4 +203,32 @@
86203 ^- $-(json [%share ship])
87204 (of share+(su ;~(pfix sig fed:ag)) ~)
88205 --
206+::
207+::
208+++ groups-link-thatch
209+'''
210+const buttonText = 'View in Astrolabe';
211+setInterval(() => {
212+ const footer = document.querySelectorAll('section > div > footer')?.[0];
213+ if (!footer) return;
214+ if (footer.children[0].innerText === buttonText) return;
215+ const spans = document.querySelectorAll('section > div > div > div > span > span:first-child');
216+ spans.forEach((span) => {
217+ if (span.innerHTML !== '~') return;
218+ if (footer.children[0].innerText === buttonText) return;
219+ let cspan = span.parentElement;
220+ let patp = cspan.innerText;
221+ let b = document.createElement('a');
222+ b.innerHTML = buttonText;
223+ b.className = 'button';
224+ // b.href = 'web+urbitgraph://astrolabe/ship/' + patp;
225+ b.href = '/apps/astrolabe/#/ship/' + patp;
226+ b.target = '_blank';
227+ b.style.backgroundColor = "navy";
228+ b.style.marginLeft = "1rem";
229+ b.style.color = "white";
230+ footer.prepend(b);
231+ });
232+}, 100);
233+'''
89234--
desk/lib/search.hoonnew file+373
@@ -0,0 +1,373 @@
1+/- sur=astrolabe
2+/+ *astrolabe
3+=< [sur .]
4+=, sur
5+|%
6+++ search-text-chars "*abcdefghilmnoprstuvwxyz"
7+++ trip-syls
8+ |= syls=cord
9+ %+ turn
10+ (rip [0 24] syls)
11+ trip
12+++ prefixes ^~ (trip-syls sis:po)
13+++ suffixes ^~ (trip-syls dex:po)
14+++ full-opts ^~ (gulf .~zod .~fes)
15+++ galaxies ^~ `(list @p)`full-opts
16+++ sanitize-search-text
17+ |= =search-text
18+ ^- tape
19+ %+ skim search-text
20+ |= a=@t
21+ !=(~ (find [a]~ search-text-chars))
22++$ pfsf ?(%prefix %suffix)
23++$ syl [=tape =pfsf]
24++$ search-text tape
25++$ search-syls (list syl) :: in reverse order, e.g. ["net" "pal" "pel" "sam" ~]. length 1-4
26++$ search-syl-opts (list @q)
27++$ search-opts (list search-syl-opts) :: must have length 4
28++$ search-full
29+ $:
30+ =search-syls
31+ =search-opts
32+ ==
33++$ mr-search :: maybe reversed full search
34+ $:
35+ [reversed=? pain=@]
36+ =search-full
37+ ==
38+++ search-syl-to-search-syl-opts
39+ |= search=syl
40+ ^- search-syl-opts
41+ =/ syls
42+ ?: =(%prefix pfsf.search) prefixes suffixes
43+ ?: =(tape.search "***") full-opts
44+ %+ murn syls
45+ |= cand=tape
46+ ?. (tape-matches tape.search cand) ~
47+ %- ?: =(%prefix pfsf.search) ins:po ind:po
48+ (crip cand)
49+++ search-text-to-search-syls
50+ |= search-text=tape
51+ ^- search-syls
52+ =. search-text (sanitize-search-text search-text)
53+ =/ syl-tapes
54+ %+ turn
55+ %- flop
56+ (rip [0 24] (crip search-text)) :: jet doesn't support rip [3 3] which is equivalent
57+ trip
58+ =| count=@
59+ |-
60+ ^- search-syls
61+ =/ =pfsf
62+ ?: =(0 (mod count 2)) %suffix %prefix
63+ ?~ syl-tapes ~
64+ :- [i.syl-tapes pfsf]
65+ $(syl-tapes t.syl-tapes, count +(count))
66+::
67+++ search-syls-to-search-opts
68+ |= =search-syls
69+ ^- search-opts
70+ =/ opts
71+ %+ turn
72+ search-syls
73+ |= =syl
74+ (search-syl-to-search-syl-opts syl)
75+ ?: %+ lien opts
76+ |= syl-opts=search-syl-opts
77+ =(~ syl-opts)
78+ ~[~ ~ ~ ~]
79+ |-
80+ ?: (gte (lent opts) 4)
81+ opts
82+ $(opts (snoc (search-opts opts) (search-syl-opts ~[.~zod])))
83+::
84+++ search-text-to-full
85+ |= search-text=tape
86+ ^- search-full
87+ =/ =search-syls (search-text-to-search-syls search-text)
88+ :- search-syls
89+ (search-syls-to-search-opts search-syls)
90+::
91+++ expand-search-text-to-len
92+ |= [search=tape flen=@ud rotate=?]
93+ =. search (sanitize-search-text search)
94+ |-
95+ ^- (list tape)
96+ =+ slen=(lent search)
97+ ?: =(slen flen)
98+ ~[search]
99+ ?: (gth slen flen) ~
100+ :-
101+ (weld search (reap (sub flen slen) '*'))
102+ ?. rotate ~
103+ $(search (weld "*" search))
104+::
105+++ expand-search-text
106+ |= search=tape
107+ ^- (list tape)
108+ =. search (sanitize-search-text search)
109+ ?~ search ~
110+ =/ rotate
111+ ?& !=('~' i.search)
112+ !(levy (tape search) (cury test '*')) :: is all wild
113+ ==
114+ =/ expand (cury expand-search-text-to-len search)
115+ ;: weld
116+ (expand 3 rotate)
117+ (expand 6 rotate)
118+ (expand 12 rotate)
119+ ==
120+::
121+++ search-text-to-fulls
122+ |= search=tape
123+ ^- (list search-full)
124+ =/ texts (expand-search-text search)
125+ %+ murn
126+ texts
127+ |= text=tape
128+ =/ full (search-text-to-full text)
129+ ?: =(~[~ ~ ~ ~] search-opts.full)
130+ ~
131+ (some full)
132+::
133+++ sigil-search-text-to-full
134+ |= text=tape
135+ ^- search-full
136+ :- ~
137+ ^- search-opts
138+ %- flop
139+ %+ turn
140+ (split "_" text)
141+ |= ints-tape=tape
142+ ^- search-syl-opts
143+ ?: =(ints-tape "any")
144+ full-opts
145+ %+ turn
146+ (split "." ints-tape)
147+ |= =tape
148+ :: ~& tape
149+ `@q`(slav %ud (crip tape))
150+::
151+++ reverse-list :: that is, put first 2 in back "abcd" -> "cdab"
152+ |* lst=(list)
153+ ^- _lst
154+ %+ weld
155+ (slag 2 lst)
156+ (scag 2 lst)
157+++ pad-search-syls
158+ |= =search-syls
159+ ^- ^search-syls
160+ =/ padding (search-text-to-search-syls "dozzoddozzod")
161+ %+ weld
162+ search-syls
163+ (slag (lent search-syls) padding)
164+++ reverse-search
165+ |= search=search-full
166+ ^- search-full
167+ :- (reverse-list (pad-search-syls search-syls.search))
168+ (reverse-list search-opts.search)
169+::
170+++ estimate-search-pain
171+ |= [search=search-full reversed=?]
172+ ^- @
173+ =/ opts search-opts.search
174+ =/ layer-wyt=@rs .255
175+ =, rs
176+ =/ pain
177+ %- :(corl abs:si need toi)
178+ |-
179+ ^- @rs
180+ ?~ opts .0
181+ =/ layer-dropoff
182+ ?: &(reversed =(i.opts `search-syl-opts`~[.~zod]))
183+ .0.99
184+ .0.1694
185+ =/ num-opts (sun (lent i.opts))
186+ =/ cen-opts (div num-opts .255)
187+ =/ num-res (mul cen-opts layer-wyt)
188+ =/ ops (mul (sqt cen-opts) layer-wyt)
189+ %^ fma num-res
190+ %= $
191+ opts t.opts
192+ layer-wyt (mul layer-wyt layer-dropoff)
193+ ==
194+ ops
195+ :: ~& "pain for {<search-syls.search>}: {<pain>}"
196+ pain
197+++ estimate-search-text-pain
198+ |= =search-text
199+ (estimate-search-pain (search-text-to-full search-text) |)
200+++ maybe-reverse-search
201+ |= [search=search-full]
202+ ^- mr-search
203+ =/ search-pain (estimate-search-pain search |)
204+ =/ rsearch (reverse-search search)
205+ =/ rsearch-pain (estimate-search-pain rsearch &)
206+ ?: (gth search-pain rsearch-pain)
207+ [[%.y rsearch-pain] rsearch]
208+ [[%.n search-pain] search]
209+::
210+++ maybe-reverse-searches
211+ |= [searches=(list search-full) pain-thresh=@]
212+ =| pain=@
213+ |-
214+ ^- (list mr-search)
215+ ?~ searches ~
216+ =/ mr (maybe-reverse-search i.searches)
217+ =/ new-pain (add pain pain.mr)
218+ ?: (gth new-pain pain-thresh)
219+ $(searches t.searches)
220+ :- mr
221+ $(searches t.searches, pain new-pain)
222+::
223+++ tape-matches
224+ |= [search=tape cand=tape]
225+ ^- ?
226+ |-
227+ ?~ search %.y
228+ ?~ cand %.n
229+ ?: |(=(i.search i.cand) =(i.search '*'))
230+ $(search t.search, cand t.cand)
231+ %.n
232+++ tosd
233+ |= [a=@ =pfsf]
234+ %- ?:(=(%prefix pfsf) tos:po tod:po)
235+ a
236+++ syl-equals
237+ |= [=syl cand=@]
238+ =((crip tape.syl) (tosd cand pfsf.syl))
239+++ syl-matches
240+ |= [=syl cand=@]
241+ :: todo check cand < 256
242+ (tape-matches tape.syl (trip (tosd cand pfsf.syl)))
243+++ syl-opts-match
244+ |= [opts=search-syl-opts cand=@]
245+ !=(~ (find ~[cand] opts))
246+++ matches-search-syls
247+ |= [search=search-syls cand-atom=@]
248+ =/ cand (rip 3 cand-atom)
249+ |-
250+ ^- ?
251+ ?~ search =(cand ~)
252+ :: =? cand =(cand ~)
253+ :: `(lest @)`~[0]
254+ ?~ cand
255+ :: ?& (syl-equals i.search 0)
256+ ?& (syl-matches i.search 0)
257+ $(search t.search)
258+ ==
259+ :: =/ nncand ^- (lest @)
260+ :: ?~ cand ~[0] cand
261+ ?& (syl-matches i.search i.cand)
262+ $(search t.search, cand t.cand)
263+ ==
264+::
265+++ matches-search-opts
266+ |= [search=search-opts cand-atom=@]
267+ =/ cand (rip 3 cand-atom)
268+ |-
269+ ^- ?
270+ ?~ search =(cand ~)
271+ ?~ cand
272+ ?& (syl-opts-match i.search 0)
273+ $(search t.search)
274+ ==
275+ :: =/ nncand ^- (lest @)
276+ :: ?~ cand ~[0] cand
277+ ?& (syl-opts-match i.search i.cand)
278+ $(search t.search, cand t.cand)
279+ ==
280+::
281+++ matches-search
282+ |= [search=search-full cand-atom=@]
283+ ?~ search-syls.search
284+ (matches-search-opts search-opts.search cand-atom)
285+ (matches-search-syls search-syls.search cand-atom)
286+::
287+++ opts-in-range
288+ |= [lb=@ rb=@ opts=(list @)]
289+ ^- search-syl-opts
290+ %+ skim
291+ opts
292+ |= a=@
293+ &((lte lb a) (gte rb a))
294+::
295+++ range-contains-search
296+ |= [lb=@ rb=@ search=search-opts] :: includes lb and rb - [lb, rb]
297+ ^- [opts=search-opts contains=?]
298+ ?~ search `%.y
299+ =/ s-0 i.search
300+ ?~ s-0 `%.n
301+ =/ lb-0 (end 3 lb)
302+ =/ rb-0 (end 3 rb)
303+ =/ cand-0 (opts-in-range lb-0 rb-0 s-0)
304+ =/ cand-0-len (lent cand-0)
305+ :: ~& "lb: {<`@q`lb>} rb: {<`@q`rb>} cand-len: {<cand-0-len>}"
306+ ?: =(0 cand-0-len) `%.n
307+ =. i.search cand-0
308+ :_
309+ ?: (gte cand-0-len 3) %.y :: entire valid galaxy is bounded
310+ =/ lb-clean =(0 (rsh 3 lb)) :: lb is galaxy
311+ =/ rb-clean =(0 (rsh 3 (add-d rb 1))) :: rb is last planet in galaxy
312+ ?: &(=(2 cand-0-len) |(lb-clean rb-clean))
313+ %.y :: two galaxies, and one is right on the edge (fully bounded)
314+ |-
315+ ^- ?
316+ ?~ cand-0 %.n
317+ =/ crb (add .~fipfes-fipzod i.cand-0)
318+ =/ slb (rev-q (rev-f max lb i.cand-0))
319+ =/ srb (rev-q (rev-f min rb crb))
320+ =/ sub-contains +:^$(lb (rsh 3 slb), rb (rsh 3 srb), search t.search)
321+ ?: sub-contains %.y
322+ $(cand-0 t.cand-0)
323+ search
324+::
325+++ run-wildcard-search
326+ |* [agg=mold search=search-full points=opoints =page-info]
327+ |= [res=[count=@ =agg] f=$-([agg @q] agg)]
328+ ^- [count=@ =agg]
329+ =/ s-opts search-opts.search
330+ =+ [llb=.~zod rrb=`@q`(sub (bex 32) 1)]
331+ :: =< +
332+ |-
333+ ^- _res
334+ ?~ points
335+ :: ~& "nothing here, going up"
336+ res
337+ :: ?: (gth count.res 1.000) ~|(%search-too-broad !!)
338+ =/ n=@q `@`-.n.points
339+ =/ lrb=@q ?: (gth n 0) (sub-d n 1) .~zod
340+ =/ rlb=@q (add-d n 1)
341+ =/ left-view (range-contains-search llb lrb s-opts)
342+ :: ~& "arrived at {<n>}"
343+ :: ~& "left side: {<?:(contains.left-view 'Y' 'N')>} {<llb>} - {<lrb>}"
344+ =/ right-view (range-contains-search rlb rrb s-opts)
345+ =? res contains.left-view
346+ $(points l.points, rrb lrb, s-opts opts.left-view)
347+ =? res (matches-search search n)
348+ =/ fits (fits-on-page count.res page-info)
349+ =. count.res +(count.res)
350+ =? agg.res fits (f agg.res n)
351+ res
352+ :: ~& "right side: {<?:(contains.right-view 'Y' 'N')>} {<rlb>} - {<rrb>}"
353+ =? res contains.right-view
354+ $(points r.points, llb rlb, s-opts opts.right-view)
355+ res
356+::
357+++ run-mr-search
358+ |= [fopoints=opoints ropoints=opoints]
359+ |= [search=mr-search res=[count=@ agg=opoints]]
360+ ^- _res
361+ =/ points ?: reversed.search ropoints fopoints
362+ =. res
363+ %+ (run-wildcard-search _agg.res search-full.search points [0 0])
364+ res
365+ |= [agg=_agg.res result=@q]
366+ =? result reversed.search
367+ (switch-words result)
368+ =. result (to-p result)
369+ (put:((on @ @) gte) agg result ~)
370+ :: ~& "returning {<~(wyt by agg.res)>} of {<count.res>} results"
371+ res
372+::
373+--
desk/lib/state.hoonnew file+21
@@ -0,0 +1,21 @@
1+/- *astrolabe
2+/+ *astrolabe
3+|%
4+++ put-in-spawn-mip
5+ |= [child=ship =npoint s=state-latest]
6+ ^- _s
7+ =/ parent (^sein:title child)
8+ ?: =(parent child) s
9+ ?: (is-npoint-locked npoint) s
10+ =/ pdata (pdata:smel (pmeta:smel child npoint) ~)
11+ =. spam.s (~(put bi spam.s) parent child pdata)
12+ =* spo sponsor.net.npoint
13+ =/ prev (~(gut by prev-spo.s) child parent)
14+ =. prev-spo.s (~(del by prev-spo.s) child)
15+ =? spam.s !=(parent prev)
16+ (~(del bi spam.s) prev child)
17+ ?. has.spo s
18+ =. prev-spo.s (~(put by prev-spo.s) child who.spo)
19+ =. spam.s (~(put bi spam.s) who.spo child pdata)
20+ s
21+--
desk/mar/astrolabe/point-set.hoonnew file+13
@@ -0,0 +1,13 @@
1+/+ *astrolabe
2+|_ points=(list ship)
3+++ grab
4+ |%
5+ ++ noun (list ship)
6+ --
7+++ grow
8+ |%
9+ ++ noun points
10+ ++ json (point-set:enjs points)
11+ --
12+++ grad %noun
13+--
desk/mar/astrolabe/point.hoon+3−3
@@ -1,9 +1,9 @@
11/+ *astrolabe
2−|_ pnt=upoint
2+|_ pnt=point
33++ grab
44 |%
5− ++ noun upoint
6− ++ json point:dejs
5+ ++ noun point
6+ :: ++ json point:dejs
77 --
88++ grow
99 |%
desk/mar/ico.hoonnew file+12
@@ -0,0 +1,12 @@
1+|_ dat=@
2+++ grow
3+ |%
4+ ++ mime [/image/x-icon (as-octs:mimes:html dat)]
5+ --
6+++ grab
7+ |%
8+ ++ mime |=([p=mite q=octs] q.q)
9+ ++ noun @
10+ --
11+++ grad %mime
12+--
desk/mar/seal.hoonnew file+12
@@ -0,0 +1,12 @@
1+|_ dat=@
2+++ grow
3+ |%
4+ ++ mime [/text (as-octs:mimes:html dat)]
5+ --
6+++ grab
7+ |%
8+ ++ mime |=([p=mite q=octs] q.q)
9+ ++ noun @
10+ --
11+++ grad %mime
12+--
desk/mar/webmanifest.hoonnew file+12
@@ -0,0 +1,12 @@
1+|_ dat=@
2+++ grow
3+ |%
4+ ++ mime [/application/'manifest+json' (as-octs:mimes:html dat)]
5+ --
6+++ grab
7+ |%
8+ ++ mime |=([p=mite q=octs] q.q)
9+ ++ noun @
10+ --
11+++ grad %mime
12+--
desk/sur/astrolabe.hoon+56−3
@@ -1,5 +1,58 @@
1−/+ naive
1+/+ naive, *mip
22|%
3−+$ point point:naive
4−++ upoint (unit point)
3++$ versioned-state
4+ $% state-0
5+ state-1
6+ state-2
7+ state-3
8+ state-4
9+ ==
10++$ state-latest state-4
11++$ state-0
12+ $: %0
13+ spa=spawned
14+ ==
15++$ state-1
16+ $: %1
17+ fropoints-1
18+ ==
19++$ state-2
20+ $: %2
21+ spam=spawn-mip
22+ fropoints-1
23+ ==
24++$ state-3
25+ $: %3
26+ prev-spo=(map ship ship) :: so we know who the old sponsor was when sponsor changes
27+ spam=spawn-mip
28+ fropoints-1
29+ ==
30++$ state-4
31+ $: %4
32+ bump=_1 :: bump to update state without changing the type
33+ prev-spo=(map ship ship) :: so we know who the old sponsor was when sponsor changes
34+ spam=spawn-mip
35+ fropoints-1
36+ ==
37+::
38++$ fropoints-1
39+ $: fopoints=opoints :: forward ordered points
40+ ropoints=opoints :: reversed ordered points, e.g. .~palnet-sampel
41+ ==
42++$ spawned (jug ship ship)
43++$ spawn-mip (mip ship ship tape)
44++$ opoints (tree [@ @]) :: ordered points [ship ~]
45+::
46++$ npoint point:naive
47+++ unpoint (unit npoint)
48++$ point
49+ $: =ship
50+ =unpoint
51+ spa-count=@ud
52+ sponsor-chain=(list ship)
53+ probable-dominion=dominion:naive
54+ ==
55++$ spawned-filter ?(%all %locked %unlocked)
56+::
57+::
558--
desk/sys.kelvin+1−1
@@ -1 +1 @@
1−[%zuse 419]
1+[%zuse 408]
desk/tests/lib/state.hoonnew file+59
@@ -0,0 +1,59 @@
1+/- *astrolabe
2+/+ *astrolabe, *state, *mip, *test
3+|%
4+++ test-put-in-spawn-mip
5+ =| state=state-latest
6+ =/ moved-to-bus=npoint
7+ =< .(who.sponsor.net ~bus)
8+ *npoint
9+ =/ moved-to-hec=npoint
10+ =< .(who.sponsor.net ~hec)
11+ *npoint
12+ ;: weld
13+ %+ expect-eq
14+ !> :-
15+ `~zod :: new prev-spo
16+ "marzod:s;" :: spawn-mip has something under ~zod
17+ !> =- :-
18+ (~(get by prev-spo) ~marzod)
19+ (~(gut bi spam) ~zod ~marzod "nothing!")
20+ (put-in-spawn-mip ~marzod *npoint state)
21+ ::
22+ %+ expect-eq
23+ !> :*
24+ `~hec :: new prev-spo
25+ "marzod:s:hec!zod;" :: under ~zod
26+ %.n :: nothing under ~bus
27+ "marzod:s:hec!zod;" :: under ~hec
28+ ==
29+ !>
30+ =. state (put-in-spawn-mip ~marzod *npoint state)
31+ =. state (put-in-spawn-mip ~marzod moved-to-bus state)
32+ =+ (put-in-spawn-mip ~marzod moved-to-hec state)
33+ :*
34+ (~(get by prev-spo) ~marzod)
35+ (~(gut bi spam) ~zod ~marzod "nothing!")
36+ (~(has by spam) ~bus)
37+ (~(gut bi spam) ~hec ~marzod "nothing!")
38+ ==
39+ ::
40+ %+ expect-eq
41+ !> :*
42+ `~zod :: new prev-spo
43+ "marzod:s;" :: under ~zod
44+ %.n :: nothing under ~bus
45+ %.n :: nothing under ~hec
46+ ==
47+ !>
48+ =. state (put-in-spawn-mip ~marzod *npoint state)
49+ =. state (put-in-spawn-mip ~marzod moved-to-bus state)
50+ =. state (put-in-spawn-mip ~marzod moved-to-hec state)
51+ =+ (put-in-spawn-mip ~marzod *npoint state)
52+ :*
53+ (~(get by prev-spo) ~marzod)
54+ (~(gut bi spam) ~zod ~marzod "nothing!")
55+ (~(has by spam) ~bus)
56+ (~(has by spam) ~hec)
57+ ==
58+ ==
59+--
docs-dev-desk/mar/toc.hoonnew file+16
@@ -0,0 +1,16 @@
1+/- docs
2+|_ tab=@t
3+++ grab
4+ |%
5+ ++ mime |=([=mite len=@ud tex=@] `@t`tex)
6+ ++ noun @t
7+ ++ txt of-wain:format
8+ --
9+++ grow
10+ |%
11+ ++ mime [/text/x-toc (as-octs:mimes:html tab)]
12+ ++ noun tab
13+ ++ txt (to-wain:format tab)
14+ --
15+++ grad %txt
16+--
flake.locknew file+27
@@ -0,0 +1,27 @@
1+{
2+ "nodes": {
3+ "nixpkgs": {
4+ "locked": {
5+ "lastModified": 1793341285,
6+ "narHash": "sha256-Y1CiZ4SoBUjLQyQM/pY+rS2dXD3CHLPstF0lmOc73D4=",
7+ "owner": "NixOS",
8+ "repo": "nixpkgs",
9+ "rev": "1c89083e451e891152365b799595cf7790a43325",
10+ "type": "github"
11+ },
12+ "original": {
13+ "owner": "NixOS",
14+ "ref": "nixos-unstable",
15+ "repo": "nixpkgs",
16+ "type": "github"
17+ }
18+ },
19+ "root": {
20+ "inputs": {
21+ "nixpkgs": "nixpkgs"
22+ }
23+ }
24+ },
25+ "root": "root",
26+ "version": 7
27+}
flake.nixnew file+73
@@ -0,0 +1,73 @@
1+{
2+ description = "Astrolabe Urbit desk";
3+
4+ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
5+
6+ outputs = { self, nixpkgs }:
7+ let
8+ systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
9+ forAllSystems = nixpkgs.lib.genAttrs systems;
10+ in
11+ {
12+ packages = forAllSystems (system:
13+ let
14+ pkgs = import nixpkgs { inherit system; };
15+ nounPy = pkgs.fetchurl {
16+ name = "noun.py";
17+ url = "https://raw.githubusercontent.com/urbit/tools/f9cda82a7699cad0c1c0f8c031a59e93f028e548/pkg/pynoun/noun.py";
18+ hash = "sha256-vSKQ/UuSmGTANfW5c3I9lQcUFycvqmu5gqysFuP5SAA=";
19+ };
20+ ui = pkgs.buildNpmPackage {
21+ pname = "astrolabe-ui";
22+ version = "0.3.0";
23+ src = ./ui;
24+ nodejs = pkgs.nodejs_22;
25+ npmDepsHash = "sha256-jCkfgNgBmq0mKjmXBbPwdpzBR/E09OgS9XD6O9hRHfw=";
26+ makeCacheWritable = true;
27+ npmFlags = [ "--legacy-peer-deps" ];
28+ npmBuildScript = "build";
29+
30+ installPhase = ''
31+ runHook preInstall
32+ cp -r dist $out
33+ runHook postInstall
34+ '';
35+ };
36+ in
37+ rec {
38+ inherit ui;
39+ desk = pkgs.stdenvNoCC.mkDerivation {
40+ pname = "astrolabe-desk";
41+ version = "1.0.7";
42+ dontUnpack = true;
43+ nativeBuildInputs = [ pkgs.rsync ];
44+
45+ installPhase = ''
46+ runHook preInstall
47+ mkdir -p $out
48+ rsync -r --copy-links --exclude-from=${./config/ignore_files_on_install.txt} ${./base-desk}/ $out/
49+ rsync -r --copy-links --exclude-from=${./config/ignore_files_on_install.txt} ${./docs-dev-desk}/ $out/
50+ rsync -r --copy-links --exclude-from=${./config/ignore_files_on_install.txt} ${./desk}/ $out/
51+ runHook postInstall
52+ '';
53+ };
54+ glob = pkgs.stdenvNoCC.mkDerivation {
55+ pname = "astrolabe-glob";
56+ version = "0.3.0";
57+ dontUnpack = true;
58+ nativeBuildInputs = [
59+ (pkgs.python3.withPackages (ps: [ ps.mmh3 ps.bitstring ]))
60+ ];
61+
62+ installPhase = ''
63+ runHook preInstall
64+ mkdir -p $TMPDIR/pynoun
65+ ln -s ${nounPy} $TMPDIR/pynoun/noun.py
66+ PYTHONPATH=$TMPDIR/pynoun python ${./bin/make_glob.py} ${ui} $out
67+ runHook postInstall
68+ '';
69+ };
70+ default = desk;
71+ });
72+ };
73+}
install.shdeleted−44
@@ -1,44 +0,0 @@
1−#!/bin/bash
2−#
3−# Taken from: https://github.com/timlucmiptev/btc-agents/blob/master/install.sh
4−# by ~timluc-miptev
5−#
6−usage() { printf "Usage: $0 [-w] URBIT_DESK_DIRECTORY \n(-w: flag to watch and live copy code)\n" 1>&2; exit 1; }
7−
8−if [ $# -eq 0 ]; then
9− usage
10− exit 2
11−fi
12−DESK=$1
13−EXCLUDE_FILE=config/ignore_files_on_install.txt
14−
15−while getopts "w" opt; do
16− case ${opt} in
17− w) WATCH_MODE="true"
18− DESK=$2
19− ;;
20− *) usage
21− ;;
22− esac
23−done
24−
25−if [ -z "$WATCH_MODE" ]; then
26− echo "Installed %astrolabe"
27− rm -r $DESK/*
28− rsync -r --copy-links --exclude-from=$EXCLUDE_FILE ./base-desk/* $DESK/
29− rsync -r --copy-links --exclude-from=$EXCLUDE_FILE ./docs-dev-desk/* $DESK/
30− rsync -r --copy-links --exclude-from=$EXCLUDE_FILE ./desk/* $DESK/
31−
32−else
33− echo "Watching for changes to copy to ${DESK}..."
34− rm -r $DESK/*
35− while [ 0 ]
36− do
37− sleep 0.8
38− rsync -r --copy-links --exclude-from=$EXCLUDE_FILE ./base-desk/* $DESK/
39− rsync -r --copy-links --exclude-from=$EXCLUDE_FILE ./docs-dev-desk/* $DESK/
40− rsync -r --copy-links --exclude-from=$EXCLUDE_FILE ./desk/* $DESK/
41−
42− done
43−fi
44−ls
ui/.envnew file+3
@@ -0,0 +1,3 @@
1+VITE_SHIP_URL=http://localhost:8081
2+ASTROLABE_DESK=~/urbit/zod/astrolabe
3+GLOBBER_DESK=~/urbit/zod/globber
ui/index.html+7−3
@@ -2,12 +2,16 @@
22<html lang="en">
33 <head>
44 <meta charset="UTF-8" />
5− <link rel="icon" href="/favicon.ico" />
5+ <!-- <link rel="icon" href="/favicon.ico" /> -->
6+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
7+ <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
8+ <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
9+ <link rel="manifest" href="/site.webmanifest">
610 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7− <title>Astrolabe</title>
11+ <meta name="color-scheme" content="light only">
812 </head>
913 <body>
10− <div id="app"></div>
14+ <div id="app" class="h-full"></div>
1115 <script type="module" src="/src/main.ts"></script>
1216 </body>
1317</html>
ui/package-lock.json+2175−5564
@@ -1,23 +1,24 @@
11{
22 "name": "urbit-astrolabe",
3− "version": "0.0.0",
3+ "version": "0.3.0",
44 "lockfileVersion": 2,
55 "requires": true,
66 "packages": {
77 "": {
88 "name": "urbit-astrolabe",
9− "version": "0.0.0",
10− "hasInstallScript": true,
9+ "version": "0.3.0",
1110 "dependencies": {
11+ "@johnhyde/sigil-js": "github:johnhyde/sigil-js",
1212 "@tlon/phonemes-js": "^1.0.0",
1313 "@tlon/sigil-js": "^1.4.5",
1414 "@urbit/api": "^2.1.0",
1515 "@urbit/http-api": "^2.1.0",
1616 "bn.js": "^5.2.0",
17− "i": "^0.3.7",
18− "npm": "^8.6.0",
19− "sass": "^1.50.0",
17+ "graphology": "^0.24.1",
18+ "lodash": "^4.17.21",
19+ "sigma-jh": "^2.4.2",
2020 "svelte-copy-to-clipboard": "^0.2.5",
21+ "svelte-markdown": "^0.2.3",
2122 "tippy.js": "^6.3.7",
2223 "urbit-ob": "^5.0.1"
2324 },
@@ -28,8 +29,10 @@
2829 "autoprefixer": "^10.4.2",
2930 "concurrently": "^7.0.0",
3031 "cross-env": "^7.0.3",
32+ "dotenv-cli": "^6.0.0",
3133 "postcss-cli": "^9.1.0",
32− "svelte": "^3.44.0",
34+ "sass": "^1.50.0",
35+ "svelte": "^3.48.0",
3336 "svelte-check": "^2.2.7",
3437 "svelte-preprocess": "^4.9.8",
3538 "svelte-spa-router": "^3.2.0",
@@ -39,6 +42,28 @@
3942 "vite": "^2.7.2"
4043 }
4144 },
45+ "../../sigil-js": {
46+ "name": "@johnhyde/sigil-js",
47+ "version": "1.4.6",
48+ "extraneous": true,
49+ "license": "MIT",
50+ "dependencies": {
51+ "invariant": "^2.2.4",
52+ "svgson": "^4.0.0",
53+ "transformation-matrix": "2.1.1"
54+ },
55+ "devDependencies": {
56+ "@types/invariant": "^2.2.31",
57+ "@types/react": "^17.0.20",
58+ "husky": "^4.2.3",
59+ "prettier": "^1.19.1",
60+ "tsdx": "^0.14.1",
61+ "typescript": "^3.8.3"
62+ },
63+ "peerDependencies": {
64+ "react": "^16 || ^17"
65+ }
66+ },
4267 "node_modules/@babel/code-frame": {
4368 "version": "7.16.7",
4469 "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
@@ -147,6 +172,19 @@
147172 "node": ">=6.9.0"
148173 }
149174 },
175+ "node_modules/@johnhyde/sigil-js": {
176+ "version": "1.4.6",
177+ "resolved": "git+ssh://git@github.com/johnhyde/sigil-js.git#f89ce78c34b5811ea19ddea4a6964ea8360e7b4d",
178+ "license": "MIT",
179+ "dependencies": {
180+ "invariant": "^2.2.4",
181+ "svgson": "^4.0.0",
182+ "transformation-matrix": "2.1.1"
183+ },
184+ "peerDependencies": {
185+ "react": "^16 || ^17"
186+ }
187+ },
150188 "node_modules/@microsoft/fetch-event-source": {
151189 "version": "2.0.1",
152190 "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz",
@@ -260,6 +298,11 @@
260298 "integrity": "sha512-aqkICXbM1oX5FfgZd2qSSAGdyo/NRxjWCamxoyi3T8iVQnzGge19HhDYzZ6NrVOW7bhcWNSq9XexWFtMzbB24A==",
261299 "dev": true
262300 },
301+ "node_modules/@types/marked": {
302+ "version": "4.0.7",
303+ "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.7.tgz",
304+ "integrity": "sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw=="
305+ },
263306 "node_modules/@types/node": {
264307 "version": "17.0.8",
265308 "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.8.tgz",
@@ -320,6 +363,11 @@
320363 "vite-plugin-rewrite-all": "^0.1.2"
321364 }
322365 },
366+ "node_modules/@yomguithereal/helpers": {
367+ "version": "1.1.1",
368+ "resolved": "https://registry.npmjs.org/@yomguithereal/helpers/-/helpers-1.1.1.tgz",
369+ "integrity": "sha512-UYvAq/XCA7xoh1juWDYsq3W0WywOB+pz8cgVnE1b45ZfdMhBvHDrgmSFG3jXeZSr2tMTYLGHFHON+ekG05Jebg=="
370+ },
323371 "node_modules/acorn": {
324372 "version": "7.4.1",
325373 "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@@ -380,6 +428,7 @@
380428 "version": "3.1.2",
381429 "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
382430 "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
431+ "dev": true,
383432 "dependencies": {
384433 "normalize-path": "^3.0.0",
385434 "picomatch": "^2.0.4"
@@ -451,6 +500,7 @@
451500 "version": "2.2.0",
452501 "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
453502 "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
503+ "dev": true,
454504 "engines": {
455505 "node": ">=8"
456506 }
@@ -474,6 +524,7 @@
474524 "version": "3.0.2",
475525 "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
476526 "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
527+ "dev": true,
477528 "dependencies": {
478529 "fill-range": "^7.0.1"
479530 },
@@ -566,6 +617,7 @@
566617 "version": "3.5.2",
567618 "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
568619 "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
620+ "dev": true,
569621 "dependencies": {
570622 "anymatch": "~3.1.2",
571623 "braces": "~3.0.2",
@@ -766,7 +818,7 @@
766818 "node_modules/deep-rename-keys": {
767819 "version": "0.2.1",
768820 "resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz",
769− "integrity": "sha1-7eeFN9emaivmFRfir5Vtf1ij8dg=",
821+ "integrity": "sha512-RHd9ABw4Fvk+gYDWqwOftG849x0bYOySl/RgX0tLI9i27ZIeSO91mLZJEp7oPHOMFqHvpgu21YptmDt0FYD/0A==",
770822 "dependencies": {
771823 "kind-of": "^3.0.2",
772824 "rename-keys": "^1.1.2"
@@ -840,6 +892,39 @@
840892 "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
841893 "dev": true
842894 },
895+ "node_modules/dotenv": {
896+ "version": "16.0.1",
897+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
898+ "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==",
899+ "dev": true,
900+ "engines": {
901+ "node": ">=12"
902+ }
903+ },
904+ "node_modules/dotenv-cli": {
905+ "version": "6.0.0",
906+ "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-6.0.0.tgz",
907+ "integrity": "sha512-qXlCOi3UMDhCWFKe0yq5sg3X+pJAz+RQDiFN38AMSbUrnY3uZshSfDJUAge951OS7J9gwLZGfsBlWRSOYz/TRg==",
908+ "dev": true,
909+ "dependencies": {
910+ "cross-spawn": "^7.0.3",
911+ "dotenv": "^16.0.0",
912+ "dotenv-expand": "^8.0.1",
913+ "minimist": "^1.2.5"
914+ },
915+ "bin": {
916+ "dotenv": "cli.js"
917+ }
918+ },
919+ "node_modules/dotenv-expand": {
920+ "version": "8.0.3",
921+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz",
922+ "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==",
923+ "dev": true,
924+ "engines": {
925+ "node": ">=12"
926+ }
927+ },
843928 "node_modules/electron-to-chromium": {
844929 "version": "1.4.38",
845930 "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.38.tgz",
@@ -1144,7 +1229,15 @@
11441229 "node_modules/eventemitter3": {
11451230 "version": "2.0.3",
11461231 "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
1147− "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
1232+ "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
1233+ },
1234+ "node_modules/events": {
1235+ "version": "3.3.0",
1236+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
1237+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
1238+ "engines": {
1239+ "node": ">=0.8.x"
1240+ }
11481241 },
11491242 "node_modules/fast-glob": {
11501243 "version": "3.2.9",
@@ -1175,6 +1268,7 @@
11751268 "version": "7.0.1",
11761269 "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
11771270 "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
1271+ "dev": true,
11781272 "dependencies": {
11791273 "to-regex-range": "^5.0.1"
11801274 },
@@ -1219,6 +1313,7 @@
12191313 "version": "2.3.2",
12201314 "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
12211315 "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
1316+ "dev": true,
12221317 "hasInstallScript": true,
12231318 "optional": true,
12241319 "os": [
@@ -1258,7 +1353,7 @@
12581353 "node_modules/get-value": {
12591354 "version": "2.0.6",
12601355 "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
1261− "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
1356+ "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==",
12621357 "engines": {
12631358 "node": ">=0.10.0"
12641359 }
@@ -1287,6 +1382,7 @@
12871382 "version": "5.1.2",
12881383 "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
12891384 "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1385+ "dev": true,
12901386 "dependencies": {
12911387 "is-glob": "^4.0.1"
12921388 },
@@ -1320,6 +1416,32 @@
13201416 "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
13211417 "dev": true
13221418 },
1419+ "node_modules/graphology": {
1420+ "version": "0.24.1",
1421+ "resolved": "https://registry.npmjs.org/graphology/-/graphology-0.24.1.tgz",
1422+ "integrity": "sha512-6lNz1PNTAe9Q6ioHKrXu0Lp047sgvOoHa4qmP/8mnJWCGv2iIZPQkuHPUb2/OWDWCqHpw2hKgJLJ55X/66xmHg==",
1423+ "dependencies": {
1424+ "events": "^3.3.0",
1425+ "obliterator": "^2.0.2"
1426+ },
1427+ "peerDependencies": {
1428+ "graphology-types": ">=0.24.0"
1429+ }
1430+ },
1431+ "node_modules/graphology-types": {
1432+ "version": "0.24.4",
1433+ "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.4.tgz",
1434+ "integrity": "sha512-CSgmycWiviCctMFO86YoUTJN1t4/PLKC5Pos2Hite+7kCUXTr+mGlDUAOgpcKG1IfFaeL9VDmTjFpzs2rTnPWw==",
1435+ "peer": true
1436+ },
1437+ "node_modules/graphology-utils": {
1438+ "version": "2.5.2",
1439+ "resolved": "https://registry.npmjs.org/graphology-utils/-/graphology-utils-2.5.2.tgz",
1440+ "integrity": "sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==",
1441+ "peerDependencies": {
1442+ "graphology-types": ">=0.23.0"
1443+ }
1444+ },
13231445 "node_modules/has": {
13241446 "version": "1.0.3",
13251447 "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -1344,7 +1466,7 @@
13441466 "node_modules/has-value": {
13451467 "version": "0.3.1",
13461468 "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
1347− "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
1469+ "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==",
13481470 "dependencies": {
13491471 "get-value": "^2.0.3",
13501472 "has-values": "^0.1.4",
@@ -1357,7 +1479,7 @@
13571479 "node_modules/has-value/node_modules/isobject": {
13581480 "version": "2.1.0",
13591481 "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
1360− "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
1482+ "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==",
13611483 "dependencies": {
13621484 "isarray": "1.0.0"
13631485 },
@@ -1368,19 +1490,11 @@
13681490 "node_modules/has-values": {
13691491 "version": "0.1.4",
13701492 "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
1371− "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
1493+ "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==",
13721494 "engines": {
13731495 "node": ">=0.10.0"
13741496 }
13751497 },
1376− "node_modules/i": {
1377− "version": "0.3.7",
1378− "resolved": "https://registry.npmjs.org/i/-/i-0.3.7.tgz",
1379− "integrity": "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==",
1380− "engines": {
1381− "node": ">=0.4"
1382− }
1383− },
13841498 "node_modules/ignore": {
13851499 "version": "5.2.0",
13861500 "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
@@ -1402,7 +1516,8 @@
14021516 "node_modules/immutable": {
14031517 "version": "4.0.0",
14041518 "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
1405− "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw=="
1519+ "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
1520+ "dev": true
14061521 },
14071522 "node_modules/import-fresh": {
14081523 "version": "3.3.0",
@@ -1454,6 +1569,7 @@
14541569 "version": "2.1.0",
14551570 "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
14561571 "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1572+ "dev": true,
14571573 "dependencies": {
14581574 "binary-extensions": "^2.0.0"
14591575 },
@@ -1482,6 +1598,7 @@
14821598 "version": "2.1.1",
14831599 "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
14841600 "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
1601+ "dev": true,
14851602 "engines": {
14861603 "node": ">=0.10.0"
14871604 }
@@ -1499,6 +1616,7 @@
14991616 "version": "4.0.3",
15001617 "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
15011618 "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1619+ "dev": true,
15021620 "dependencies": {
15031621 "is-extglob": "^2.1.1"
15041622 },
@@ -1510,6 +1628,7 @@
15101628 "version": "7.0.0",
15111629 "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
15121630 "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1631+ "dev": true,
15131632 "engines": {
15141633 "node": ">=0.12.0"
15151634 }
@@ -1528,7 +1647,7 @@
15281647 "node_modules/isarray": {
15291648 "version": "1.0.0",
15301649 "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1531− "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
1650+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
15321651 },
15331652 "node_modules/isexe": {
15341653 "version": "2.0.0",
@@ -1539,7 +1658,7 @@
15391658 "node_modules/isobject": {
15401659 "version": "3.0.1",
15411660 "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
1542− "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
1661+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
15431662 "engines": {
15441663 "node": ">=0.10.0"
15451664 }
@@ -1570,7 +1689,7 @@
15701689 "node_modules/kind-of": {
15711690 "version": "3.2.2",
15721691 "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
1573− "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
1692+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
15741693 "dependencies": {
15751694 "is-buffer": "^1.1.5"
15761695 },
@@ -1605,8 +1724,7 @@
16051724 "node_modules/lodash": {
16061725 "version": "4.17.21",
16071726 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
1608− "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
1609− "dev": true
1727+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
16101728 },
16111729 "node_modules/lodash.chunk": {
16121730 "version": "4.2.0",
@@ -1638,6 +1756,17 @@
16381756 "sourcemap-codec": "^1.4.4"
16391757 }
16401758 },
1759+ "node_modules/marked": {
1760+ "version": "4.2.3",
1761+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz",
1762+ "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==",
1763+ "bin": {
1764+ "marked": "bin/marked.js"
1765+ },
1766+ "engines": {
1767+ "node": ">= 12"
1768+ }
1769+ },
16411770 "node_modules/merge2": {
16421771 "version": "1.4.1",
16431772 "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -1736,6 +1865,7 @@
17361865 "version": "3.0.0",
17371866 "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
17381867 "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1868+ "dev": true,
17391869 "engines": {
17401870 "node": ">=0.10.0"
17411871 }
@@ -1749,6066 +1879,2519 @@
17491879 "node": ">=0.10.0"
17501880 }
17511881 },
1752− "node_modules/npm": {
1753− "version": "8.6.0",
1754− "resolved": "https://registry.npmjs.org/npm/-/npm-8.6.0.tgz",
1755− "integrity": "sha512-icekvN8FJFESIFkLaFEVl05Nocl5Id5HnoVhJzhCUvtNY8tj9kfUlH/J527fZq/8ltsAUqpettfutwRjQYS2fA==",
1756− "bundleDependencies": [
1757− "@isaacs/string-locale-compare",
1758− "@npmcli/arborist",
1759− "@npmcli/ci-detect",
1760− "@npmcli/config",
1761− "@npmcli/fs",
1762− "@npmcli/map-workspaces",
1763− "@npmcli/package-json",
1764− "@npmcli/run-script",
1765− "abbrev",
1766− "ansicolors",
1767− "ansistyles",
1768− "archy",
1769− "cacache",
1770− "chalk",
1771− "chownr",
1772− "cli-columns",
1773− "cli-table3",
1774− "columnify",
1775− "fastest-levenshtein",
1776− "glob",
1777− "graceful-fs",
1778− "hosted-git-info",
1779− "ini",
1780− "init-package-json",
1781− "is-cidr",
1782− "json-parse-even-better-errors",
1783− "libnpmaccess",
1784− "libnpmdiff",
1785− "libnpmexec",
1786− "libnpmfund",
1787− "libnpmhook",
1788− "libnpmorg",
1789− "libnpmpack",
1790− "libnpmpublish",
1791− "libnpmsearch",
1792− "libnpmteam",
1793− "libnpmversion",
1794− "make-fetch-happen",
1795− "minipass",
1796− "minipass-pipeline",
1797− "mkdirp",
1798− "mkdirp-infer-owner",
1799− "ms",
1800− "node-gyp",
1801− "nopt",
1802− "npm-audit-report",
1803− "npm-install-checks",
1804− "npm-package-arg",
1805− "npm-pick-manifest",
1806− "npm-profile",
1807− "npm-registry-fetch",
1808− "npm-user-validate",
1809− "npmlog",
1810− "opener",
1811− "pacote",
1812− "parse-conflict-json",
1813− "proc-log",
1814− "qrcode-terminal",
1815− "read",
1816− "read-package-json",
1817− "read-package-json-fast",
1818− "readdir-scoped-modules",
1819− "rimraf",
1820− "semver",
1821− "ssri",
1822− "tar",
1823− "text-table",
1824− "tiny-relative-date",
1825− "treeverse",
1826− "validate-npm-package-name",
1827− "which",
1828− "write-file-atomic"
1829− ],
1830− "dependencies": {
1831− "@isaacs/string-locale-compare": "^1.1.0",
1832− "@npmcli/arborist": "^5.0.4",
1833− "@npmcli/ci-detect": "^2.0.0",
1834− "@npmcli/config": "^4.0.1",
1835− "@npmcli/fs": "^2.1.0",
1836− "@npmcli/map-workspaces": "^2.0.2",
1837− "@npmcli/package-json": "^1.0.1",
1838− "@npmcli/run-script": "^3.0.1",
1839− "abbrev": "~1.1.1",
1840− "ansicolors": "~0.3.2",
1841− "ansistyles": "~0.1.3",
1842− "archy": "~1.0.0",
1843− "cacache": "^16.0.3",
1844− "chalk": "^4.1.2",
1845− "chownr": "^2.0.0",
1846− "cli-columns": "^4.0.0",
1847− "cli-table3": "^0.6.1",
1848− "columnify": "^1.6.0",
1849− "fastest-levenshtein": "^1.0.12",
1850− "glob": "^7.2.0",
1851− "graceful-fs": "^4.2.9",
1852− "hosted-git-info": "^5.0.0",
1853− "ini": "^2.0.0",
1854− "init-package-json": "^3.0.2",
1855− "is-cidr": "^4.0.2",
1856− "json-parse-even-better-errors": "^2.3.1",
1857− "libnpmaccess": "^6.0.2",
1858− "libnpmdiff": "^4.0.2",
1859− "libnpmexec": "^4.0.2",
1860− "libnpmfund": "^3.0.1",
1861− "libnpmhook": "^8.0.2",
1862− "libnpmorg": "^4.0.2",
1863− "libnpmpack": "^4.0.2",
1864− "libnpmpublish": "^6.0.2",
1865− "libnpmsearch": "^5.0.2",
1866− "libnpmteam": "^4.0.2",
1867− "libnpmversion": "^3.0.1",
1868− "make-fetch-happen": "^10.1.1",
1869− "minipass": "^3.1.6",
1870− "minipass-pipeline": "^1.2.4",
1871− "mkdirp": "^1.0.4",
1872− "mkdirp-infer-owner": "^2.0.0",
1873− "ms": "^2.1.2",
1874− "node-gyp": "^9.0.0",
1875− "nopt": "^5.0.0",
1876− "npm-audit-report": "^3.0.0",
1877− "npm-install-checks": "^4.0.0",
1878− "npm-package-arg": "^9.0.1",
1879− "npm-pick-manifest": "^7.0.0",
1880− "npm-profile": "^6.0.2",
1881− "npm-registry-fetch": "^13.1.0",
1882− "npm-user-validate": "^1.0.1",
1883− "npmlog": "^6.0.1",
1884− "opener": "^1.5.2",
1885− "pacote": "^13.0.5",
1886− "parse-conflict-json": "^2.0.2",
1887− "proc-log": "^2.0.1",
1888− "qrcode-terminal": "^0.12.0",
1889− "read": "~1.0.7",
1890− "read-package-json": "^5.0.0",
1891− "read-package-json-fast": "^2.0.3",
1892− "readdir-scoped-modules": "^1.1.0",
1893− "rimraf": "^3.0.2",
1894− "semver": "^7.3.5",
1895− "ssri": "^8.0.1",
1896− "tar": "^6.1.11",
1897− "text-table": "~0.2.0",
1898− "tiny-relative-date": "^1.3.0",
1899− "treeverse": "^1.0.4",
1900− "validate-npm-package-name": "^4.0.0",
1901− "which": "^2.0.2",
1902− "write-file-atomic": "^4.0.1"
1903− },
1904− "bin": {
1905− "npm": "bin/npm-cli.js",
1906− "npx": "bin/npx-cli.js"
1907− },
1882+ "node_modules/object-assign": {
1883+ "version": "4.1.1",
1884+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1885+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1886+ "peer": true,
19081887 "engines": {
1909− "node": "^12.13.0 || ^14.15.0 || >=16"
1888+ "node": ">=0.10.0"
19101889 }
19111890 },
1912− "node_modules/npm/node_modules/@gar/promisify": {
1913− "version": "1.1.3",
1914− "inBundle": true,
1915− "license": "MIT"
1916− },
1917− "node_modules/npm/node_modules/@isaacs/string-locale-compare": {
1918− "version": "1.1.0",
1919− "inBundle": true,
1920− "license": "ISC"
1921− },
1922− "node_modules/npm/node_modules/@npmcli/arborist": {
1923− "version": "5.0.4",
1924− "inBundle": true,
1925− "license": "ISC",
1926− "dependencies": {
1927− "@isaacs/string-locale-compare": "^1.1.0",
1928− "@npmcli/installed-package-contents": "^1.0.7",
1929− "@npmcli/map-workspaces": "^2.0.0",
1930− "@npmcli/metavuln-calculator": "^3.0.1",
1931− "@npmcli/move-file": "^1.1.0",
1932− "@npmcli/name-from-folder": "^1.0.1",
1933− "@npmcli/node-gyp": "^1.0.3",
1934− "@npmcli/package-json": "^1.0.1",
1935− "@npmcli/run-script": "^3.0.0",
1936− "bin-links": "^3.0.0",
1937− "cacache": "^16.0.0",
1938− "common-ancestor-path": "^1.0.1",
1939− "json-parse-even-better-errors": "^2.3.1",
1940− "json-stringify-nice": "^1.1.4",
1941− "mkdirp": "^1.0.4",
1942− "mkdirp-infer-owner": "^2.0.0",
1943− "nopt": "^5.0.0",
1944− "npm-install-checks": "^4.0.0",
1945− "npm-package-arg": "^9.0.0",
1946− "npm-pick-manifest": "^7.0.0",
1947− "npm-registry-fetch": "^13.0.0",
1948− "npmlog": "^6.0.1",
1949− "pacote": "^13.0.5",
1950− "parse-conflict-json": "^2.0.1",
1951− "proc-log": "^2.0.0",
1952− "promise-all-reject-late": "^1.0.0",
1953− "promise-call-limit": "^1.0.1",
1954− "read-package-json-fast": "^2.0.2",
1955− "readdir-scoped-modules": "^1.1.0",
1956− "rimraf": "^3.0.2",
1957− "semver": "^7.3.5",
1958− "ssri": "^8.0.1",
1959− "treeverse": "^1.0.4",
1960− "walk-up-path": "^1.0.0"
1961− },
1962− "bin": {
1963− "arborist": "bin/index.js"
1964− },
1891+ "node_modules/object-hash": {
1892+ "version": "2.2.0",
1893+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
1894+ "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
1895+ "dev": true,
19651896 "engines": {
1966− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
1897+ "node": ">= 6"
19671898 }
19681899 },
1969− "node_modules/npm/node_modules/@npmcli/ci-detect": {
1970− "version": "2.0.0",
1971− "inBundle": true,
1972− "license": "ISC",
1973− "engines": {
1974− "node": "^12.13.0 || ^14.15.0 || >=16"
1975− }
1900+ "node_modules/obliterator": {
1901+ "version": "2.0.4",
1902+ "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz",
1903+ "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ=="
19761904 },
1977− "node_modules/npm/node_modules/@npmcli/config": {
1978− "version": "4.0.1",
1979− "inBundle": true,
1980− "license": "ISC",
1905+ "node_modules/omit-deep": {
1906+ "version": "0.3.0",
1907+ "resolved": "https://registry.npmjs.org/omit-deep/-/omit-deep-0.3.0.tgz",
1908+ "integrity": "sha512-Lbl/Ma59sss2b15DpnWnGmECBRL8cRl/PjPbPMVW+Y8zIQzRrwMaI65Oy6HvxyhYeILVKBJb2LWeG81bj5zbMg==",
19811909 "dependencies": {
1982− "@npmcli/map-workspaces": "^2.0.1",
1983− "ini": "^2.0.0",
1984− "mkdirp-infer-owner": "^2.0.0",
1985− "nopt": "^5.0.0",
1986− "proc-log": "^2.0.0",
1987− "read-package-json-fast": "^2.0.3",
1988− "semver": "^7.3.5",
1989− "walk-up-path": "^1.0.0"
1910+ "is-plain-object": "^2.0.1",
1911+ "unset-value": "^0.1.1"
19901912 },
19911913 "engines": {
1992− "node": "^12.13.0 || ^14.15.0 || >=16"
1914+ "node": ">=0.10.0"
19931915 }
19941916 },
1995− "node_modules/npm/node_modules/@npmcli/disparity-colors": {
1996− "version": "1.0.1",
1997− "inBundle": true,
1998− "license": "ISC",
1917+ "node_modules/once": {
1918+ "version": "1.4.0",
1919+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1920+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1921+ "dev": true,
19991922 "dependencies": {
2000− "ansi-styles": "^4.3.0"
2001− },
2002− "engines": {
2003− "node": ">=10"
1923+ "wrappy": "1"
20041924 }
20051925 },
2006− "node_modules/npm/node_modules/@npmcli/fs": {
2007− "version": "2.1.0",
2008− "inBundle": true,
2009− "license": "ISC",
1926+ "node_modules/parent-module": {
1927+ "version": "1.0.1",
1928+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
1929+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
1930+ "dev": true,
20101931 "dependencies": {
2011− "@gar/promisify": "^1.1.3",
2012− "semver": "^7.3.5"
1932+ "callsites": "^3.0.0"
20131933 },
20141934 "engines": {
2015− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
1935+ "node": ">=6"
20161936 }
20171937 },
2018− "node_modules/npm/node_modules/@npmcli/git": {
2019− "version": "3.0.0",
2020− "inBundle": true,
2021− "license": "ISC",
1938+ "node_modules/parse-json": {
1939+ "version": "5.2.0",
1940+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
1941+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
1942+ "dev": true,
20221943 "dependencies": {
2023− "@npmcli/promise-spawn": "^1.3.2",
2024− "lru-cache": "^7.3.1",
2025− "mkdirp": "^1.0.4",
2026− "npm-pick-manifest": "^7.0.0",
2027− "proc-log": "^2.0.0",
2028− "promise-inflight": "^1.0.1",
2029− "promise-retry": "^2.0.1",
2030− "semver": "^7.3.5",
2031− "which": "^2.0.2"
1944+ "@babel/code-frame": "^7.0.0",
1945+ "error-ex": "^1.3.1",
1946+ "json-parse-even-better-errors": "^2.3.0",
1947+ "lines-and-columns": "^1.1.6"
20321948 },
20331949 "engines": {
2034− "node": "^12.13.0 || ^14.15.0 || >=16"
2035− }
2036− },
2037− "node_modules/npm/node_modules/@npmcli/installed-package-contents": {
2038− "version": "1.0.7",
2039− "inBundle": true,
2040− "license": "ISC",
2041− "dependencies": {
2042− "npm-bundled": "^1.1.1",
2043− "npm-normalize-package-bin": "^1.0.1"
2044− },
2045− "bin": {
2046− "installed-package-contents": "index.js"
1950+ "node": ">=8"
20471951 },
2048− "engines": {
2049− "node": ">= 10"
1952+ "funding": {
1953+ "url": "https://github.com/sponsors/sindresorhus"
20501954 }
20511955 },
2052− "node_modules/npm/node_modules/@npmcli/map-workspaces": {
2053− "version": "2.0.2",
2054− "inBundle": true,
2055− "license": "ISC",
2056− "dependencies": {
2057− "@npmcli/name-from-folder": "^1.0.1",
2058− "glob": "^7.2.0",
2059− "minimatch": "^5.0.1",
2060− "read-package-json-fast": "^2.0.3"
2061− },
1956+ "node_modules/path-is-absolute": {
1957+ "version": "1.0.1",
1958+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1959+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
1960+ "dev": true,
20621961 "engines": {
2063− "node": "^12.13.0 || ^14.15.0 || >=16"
2064− }
2065− },
2066− "node_modules/npm/node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": {
2067− "version": "2.0.1",
2068− "inBundle": true,
2069− "license": "MIT",
2070− "dependencies": {
2071− "balanced-match": "^1.0.0"
1962+ "node": ">=0.10.0"
20721963 }
20731964 },
2074− "node_modules/npm/node_modules/@npmcli/map-workspaces/node_modules/minimatch": {
2075− "version": "5.0.1",
2076− "inBundle": true,
2077− "license": "ISC",
2078− "dependencies": {
2079− "brace-expansion": "^2.0.1"
2080− },
1965+ "node_modules/path-key": {
1966+ "version": "3.1.1",
1967+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1968+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1969+ "dev": true,
20811970 "engines": {
2082− "node": ">=10"
1971+ "node": ">=8"
20831972 }
20841973 },
2085− "node_modules/npm/node_modules/@npmcli/metavuln-calculator": {
2086− "version": "3.0.1",
2087− "inBundle": true,
2088− "license": "ISC",
2089− "dependencies": {
2090− "cacache": "^16.0.0",
2091− "json-parse-even-better-errors": "^2.3.1",
2092− "pacote": "^13.0.3",
2093− "semver": "^7.3.5"
2094− },
2095− "engines": {
2096− "node": "^12.13.0 || ^14.15.0 || >=16"
2097− }
1974+ "node_modules/path-parse": {
1975+ "version": "1.0.7",
1976+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1977+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1978+ "dev": true
20981979 },
2099− "node_modules/npm/node_modules/@npmcli/move-file": {
2100− "version": "1.1.2",
2101− "inBundle": true,
2102− "license": "MIT",
2103− "dependencies": {
2104− "mkdirp": "^1.0.4",
2105− "rimraf": "^3.0.2"
2106− },
1980+ "node_modules/path-type": {
1981+ "version": "4.0.0",
1982+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
1983+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
1984+ "dev": true,
21071985 "engines": {
2108− "node": ">=10"
2109− }
2110− },
2111− "node_modules/npm/node_modules/@npmcli/name-from-folder": {
2112− "version": "1.0.1",
2113− "inBundle": true,
2114− "license": "ISC"
2115− },
2116− "node_modules/npm/node_modules/@npmcli/node-gyp": {
2117− "version": "1.0.3",
2118− "inBundle": true,
2119− "license": "ISC"
2120− },
2121− "node_modules/npm/node_modules/@npmcli/package-json": {
2122− "version": "1.0.1",
2123− "inBundle": true,
2124− "license": "ISC",
2125− "dependencies": {
2126− "json-parse-even-better-errors": "^2.3.1"
1986+ "node": ">=8"
21271987 }
21281988 },
2129− "node_modules/npm/node_modules/@npmcli/promise-spawn": {
2130− "version": "1.3.2",
2131− "inBundle": true,
2132− "license": "ISC",
2133− "dependencies": {
2134− "infer-owner": "^1.0.4"
2135− }
1989+ "node_modules/picocolors": {
1990+ "version": "1.0.0",
1991+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
1992+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
1993+ "dev": true
21361994 },
2137− "node_modules/npm/node_modules/@npmcli/run-script": {
2138− "version": "3.0.1",
2139− "inBundle": true,
2140− "license": "ISC",
2141− "dependencies": {
2142− "@npmcli/node-gyp": "^1.0.3",
2143− "@npmcli/promise-spawn": "^1.3.2",
2144− "node-gyp": "^9.0.0",
2145− "read-package-json-fast": "^2.0.3"
2146− },
1995+ "node_modules/picomatch": {
1996+ "version": "2.3.1",
1997+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1998+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1999+ "dev": true,
21472000 "engines": {
2148− "node": "^12.13.0 || ^14.15.0 || >=16"
2001+ "node": ">=8.6"
2002+ },
2003+ "funding": {
2004+ "url": "https://github.com/sponsors/jonschlinkert"
21492005 }
21502006 },
2151− "node_modules/npm/node_modules/@tootallnate/once": {
2152− "version": "2.0.0",
2153− "inBundle": true,
2154− "license": "MIT",
2007+ "node_modules/pify": {
2008+ "version": "2.3.0",
2009+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
2010+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
2011+ "dev": true,
21552012 "engines": {
2156− "node": ">= 10"
2013+ "node": ">=0.10.0"
21572014 }
21582015 },
2159− "node_modules/npm/node_modules/abbrev": {
2160− "version": "1.1.1",
2161− "inBundle": true,
2162− "license": "ISC"
2163− },
2164− "node_modules/npm/node_modules/agent-base": {
2165− "version": "6.0.2",
2166− "inBundle": true,
2167− "license": "MIT",
2016+ "node_modules/postcss": {
2017+ "version": "8.4.5",
2018+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
2019+ "integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
2020+ "dev": true,
21682021 "dependencies": {
2169− "debug": "4"
2022+ "nanoid": "^3.1.30",
2023+ "picocolors": "^1.0.0",
2024+ "source-map-js": "^1.0.1"
21702025 },
21712026 "engines": {
2172− "node": ">= 6.0.0"
2027+ "node": "^10 || ^12 || >=14"
2028+ },
2029+ "funding": {
2030+ "type": "opencollective",
2031+ "url": "https://opencollective.com/postcss/"
21732032 }
21742033 },
2175− "node_modules/npm/node_modules/agentkeepalive": {
2176− "version": "4.2.1",
2177− "inBundle": true,
2178− "license": "MIT",
2034+ "node_modules/postcss-cli": {
2035+ "version": "9.1.0",
2036+ "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-9.1.0.tgz",
2037+ "integrity": "sha512-zvDN2ADbWfza42sAnj+O2uUWyL0eRL1V+6giM2vi4SqTR3gTYy8XzcpfwccayF2szcUif0HMmXiEaDv9iEhcpw==",
2038+ "dev": true,
21792039 "dependencies": {
2180− "debug": "^4.1.0",
2181− "depd": "^1.1.2",
2182− "humanize-ms": "^1.2.1"
2040+ "chokidar": "^3.3.0",
2041+ "dependency-graph": "^0.11.0",
2042+ "fs-extra": "^10.0.0",
2043+ "get-stdin": "^9.0.0",
2044+ "globby": "^12.0.0",
2045+ "picocolors": "^1.0.0",
2046+ "postcss-load-config": "^3.0.0",
2047+ "postcss-reporter": "^7.0.0",
2048+ "pretty-hrtime": "^1.0.3",
2049+ "read-cache": "^1.0.0",
2050+ "slash": "^4.0.0",
2051+ "yargs": "^17.0.0"
2052+ },
2053+ "bin": {
2054+ "postcss": "index.js"
21832055 },
21842056 "engines": {
2185− "node": ">= 8.0.0"
2057+ "node": ">=12"
2058+ },
2059+ "peerDependencies": {
2060+ "postcss": "^8.0.0"
21862061 }
21872062 },
2188− "node_modules/npm/node_modules/aggregate-error": {
2189− "version": "3.1.0",
2190− "inBundle": true,
2191− "license": "MIT",
2063+ "node_modules/postcss-cli/node_modules/yargs": {
2064+ "version": "17.3.1",
2065+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
2066+ "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
2067+ "dev": true,
21922068 "dependencies": {
2193− "clean-stack": "^2.0.0",
2194− "indent-string": "^4.0.0"
2069+ "cliui": "^7.0.2",
2070+ "escalade": "^3.1.1",
2071+ "get-caller-file": "^2.0.5",
2072+ "require-directory": "^2.1.1",
2073+ "string-width": "^4.2.3",
2074+ "y18n": "^5.0.5",
2075+ "yargs-parser": "^21.0.0"
21952076 },
21962077 "engines": {
2197− "node": ">=8"
2078+ "node": ">=12"
21982079 }
21992080 },
2200− "node_modules/npm/node_modules/ansi-regex": {
2201− "version": "5.0.1",
2202− "inBundle": true,
2203− "license": "MIT",
2081+ "node_modules/postcss-cli/node_modules/yargs-parser": {
2082+ "version": "21.0.0",
2083+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz",
2084+ "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==",
2085+ "dev": true,
22042086 "engines": {
2205− "node": ">=8"
2087+ "node": ">=12"
22062088 }
22072089 },
2208− "node_modules/npm/node_modules/ansi-styles": {
2209− "version": "4.3.0",
2210− "inBundle": true,
2211− "license": "MIT",
2090+ "node_modules/postcss-js": {
2091+ "version": "4.0.0",
2092+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz",
2093+ "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==",
2094+ "dev": true,
22122095 "dependencies": {
2213− "color-convert": "^2.0.1"
2096+ "camelcase-css": "^2.0.1"
22142097 },
22152098 "engines": {
2216− "node": ">=8"
2099+ "node": "^12 || ^14 || >= 16"
22172100 },
22182101 "funding": {
2219− "url": "https://github.com/chalk/ansi-styles?sponsor=1"
2102+ "type": "opencollective",
2103+ "url": "https://opencollective.com/postcss/"
2104+ },
2105+ "peerDependencies": {
2106+ "postcss": "^8.3.3"
22202107 }
22212108 },
2222− "node_modules/npm/node_modules/ansicolors": {
2223− "version": "0.3.2",
2224− "inBundle": true,
2225− "license": "MIT"
2226− },
2227− "node_modules/npm/node_modules/ansistyles": {
2228− "version": "0.1.3",
2229− "inBundle": true,
2230− "license": "MIT"
2231− },
2232− "node_modules/npm/node_modules/aproba": {
2233− "version": "2.0.0",
2234− "inBundle": true,
2235− "license": "ISC"
2236− },
2237− "node_modules/npm/node_modules/archy": {
2238− "version": "1.0.0",
2239− "inBundle": true,
2240− "license": "MIT"
2241− },
2242− "node_modules/npm/node_modules/are-we-there-yet": {
2243− "version": "3.0.0",
2244− "inBundle": true,
2245− "license": "ISC",
2109+ "node_modules/postcss-load-config": {
2110+ "version": "3.1.1",
2111+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.1.tgz",
2112+ "integrity": "sha512-c/9XYboIbSEUZpiD1UQD0IKiUe8n9WHYV7YFe7X7J+ZwCsEKkUJSFWjS9hBU1RR9THR7jMXst8sxiqP0jjo2mg==",
2113+ "dev": true,
22462114 "dependencies": {
2247− "delegates": "^1.0.0",
2248− "readable-stream": "^3.6.0"
2115+ "lilconfig": "^2.0.4",
2116+ "yaml": "^1.10.2"
22492117 },
22502118 "engines": {
2251− "node": "^12.13.0 || ^14.15.0 || >=16"
2119+ "node": ">= 10"
2120+ },
2121+ "funding": {
2122+ "type": "opencollective",
2123+ "url": "https://opencollective.com/postcss/"
2124+ },
2125+ "peerDependencies": {
2126+ "ts-node": ">=9.0.0"
2127+ },
2128+ "peerDependenciesMeta": {
2129+ "ts-node": {
2130+ "optional": true
2131+ }
22522132 }
22532133 },
2254− "node_modules/npm/node_modules/asap": {
2255− "version": "2.0.6",
2256− "inBundle": true,
2257− "license": "MIT"
2258− },
2259− "node_modules/npm/node_modules/balanced-match": {
2260− "version": "1.0.2",
2261− "inBundle": true,
2262− "license": "MIT"
2263− },
2264− "node_modules/npm/node_modules/bin-links": {
2265− "version": "3.0.0",
2266− "inBundle": true,
2267− "license": "ISC",
2134+ "node_modules/postcss-nested": {
2135+ "version": "5.0.6",
2136+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz",
2137+ "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==",
2138+ "dev": true,
22682139 "dependencies": {
2269− "cmd-shim": "^4.0.1",
2270− "mkdirp-infer-owner": "^2.0.0",
2271− "npm-normalize-package-bin": "^1.0.0",
2272− "read-cmd-shim": "^2.0.0",
2273− "rimraf": "^3.0.0",
2274− "write-file-atomic": "^4.0.0"
2140+ "postcss-selector-parser": "^6.0.6"
22752141 },
22762142 "engines": {
2277− "node": "^12.13.0 || ^14.15.0 || >=16"
2278− }
2279− },
2280− "node_modules/npm/node_modules/binary-extensions": {
2281− "version": "2.2.0",
2282− "inBundle": true,
2283− "license": "MIT",
2284− "engines": {
2285− "node": ">=8"
2286− }
2287− },
2288− "node_modules/npm/node_modules/brace-expansion": {
2289− "version": "1.1.11",
2290− "inBundle": true,
2291− "license": "MIT",
2292− "dependencies": {
2293− "balanced-match": "^1.0.0",
2294− "concat-map": "0.0.1"
2295− }
2296− },
2297− "node_modules/npm/node_modules/builtins": {
2298− "version": "5.0.0",
2299− "inBundle": true,
2300− "license": "MIT",
2301− "dependencies": {
2302− "semver": "^7.0.0"
2143+ "node": ">=12.0"
2144+ },
2145+ "funding": {
2146+ "type": "opencollective",
2147+ "url": "https://opencollective.com/postcss/"
2148+ },
2149+ "peerDependencies": {
2150+ "postcss": "^8.2.14"
23032151 }
23042152 },
2305− "node_modules/npm/node_modules/cacache": {
2306− "version": "16.0.3",
2307− "inBundle": true,
2308− "license": "ISC",
2309− "dependencies": {
2310− "@npmcli/fs": "^2.1.0",
2311− "@npmcli/move-file": "^1.1.2",
2312− "chownr": "^2.0.0",
2313− "fs-minipass": "^2.1.0",
2314− "glob": "^7.2.0",
2315− "infer-owner": "^1.0.4",
2316− "lru-cache": "^7.7.1",
2317− "minipass": "^3.1.6",
2318− "minipass-collect": "^1.0.2",
2319− "minipass-flush": "^1.0.5",
2320− "minipass-pipeline": "^1.2.4",
2321− "mkdirp": "^1.0.4",
2322− "p-map": "^4.0.0",
2323− "promise-inflight": "^1.0.1",
2324− "rimraf": "^3.0.2",
2325− "ssri": "^8.0.1",
2326− "tar": "^6.1.11",
2327− "unique-filename": "^1.1.1"
2328− },
2329− "engines": {
2330− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2331− }
2332− },
2333− "node_modules/npm/node_modules/chalk": {
2334− "version": "4.1.2",
2335− "inBundle": true,
2336− "license": "MIT",
2153+ "node_modules/postcss-reporter": {
2154+ "version": "7.0.5",
2155+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.5.tgz",
2156+ "integrity": "sha512-glWg7VZBilooZGOFPhN9msJ3FQs19Hie7l5a/eE6WglzYqVeH3ong3ShFcp9kDWJT1g2Y/wd59cocf9XxBtkWA==",
2157+ "dev": true,
23372158 "dependencies": {
2338− "ansi-styles": "^4.1.0",
2339− "supports-color": "^7.1.0"
2159+ "picocolors": "^1.0.0",
2160+ "thenby": "^1.3.4"
23402161 },
23412162 "engines": {
23422163 "node": ">=10"
23432164 },
23442165 "funding": {
2345− "url": "https://github.com/chalk/chalk?sponsor=1"
2346− }
2347− },
2348− "node_modules/npm/node_modules/chownr": {
2349− "version": "2.0.0",
2350− "inBundle": true,
2351− "license": "ISC",
2352− "engines": {
2353− "node": ">=10"
2166+ "type": "opencollective",
2167+ "url": "https://opencollective.com/postcss/"
2168+ },
2169+ "peerDependencies": {
2170+ "postcss": "^8.1.0"
23542171 }
23552172 },
2356− "node_modules/npm/node_modules/cidr-regex": {
2357− "version": "3.1.1",
2358− "inBundle": true,
2359− "license": "BSD-2-Clause",
2173+ "node_modules/postcss-selector-parser": {
2174+ "version": "6.0.8",
2175+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz",
2176+ "integrity": "sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==",
2177+ "dev": true,
23602178 "dependencies": {
2361− "ip-regex": "^4.1.0"
2179+ "cssesc": "^3.0.0",
2180+ "util-deprecate": "^1.0.2"
23622181 },
23632182 "engines": {
2364− "node": ">=10"
2183+ "node": ">=4"
23652184 }
23662185 },
2367− "node_modules/npm/node_modules/clean-stack": {
2368− "version": "2.2.0",
2369− "inBundle": true,
2370− "license": "MIT",
2371− "engines": {
2372− "node": ">=6"
2373− }
2186+ "node_modules/postcss-value-parser": {
2187+ "version": "4.2.0",
2188+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
2189+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
2190+ "dev": true
23742191 },
2375− "node_modules/npm/node_modules/cli-columns": {
2376− "version": "4.0.0",
2377− "inBundle": true,
2378− "license": "MIT",
2379− "dependencies": {
2380− "string-width": "^4.2.3",
2381− "strip-ansi": "^6.0.1"
2382− },
2192+ "node_modules/pretty-hrtime": {
2193+ "version": "1.0.3",
2194+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
2195+ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
2196+ "dev": true,
23832197 "engines": {
2384− "node": ">= 10"
2198+ "node": ">= 0.8"
23852199 }
23862200 },
2387− "node_modules/npm/node_modules/cli-table3": {
2388− "version": "0.6.1",
2389− "inBundle": true,
2390− "license": "MIT",
2391− "dependencies": {
2392− "string-width": "^4.2.0"
2393− },
2201+ "node_modules/queue-microtask": {
2202+ "version": "1.2.3",
2203+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
2204+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
2205+ "dev": true,
2206+ "funding": [
2207+ {
2208+ "type": "github",
2209+ "url": "https://github.com/sponsors/feross"
2210+ },
2211+ {
2212+ "type": "patreon",
2213+ "url": "https://www.patreon.com/feross"
2214+ },
2215+ {
2216+ "type": "consulting",
2217+ "url": "https://feross.org/support"
2218+ }
2219+ ]
2220+ },
2221+ "node_modules/quick-lru": {
2222+ "version": "5.1.1",
2223+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
2224+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
2225+ "dev": true,
23942226 "engines": {
2395− "node": "10.* || >= 12.*"
2227+ "node": ">=10"
23962228 },
2397− "optionalDependencies": {
2398− "colors": "1.4.0"
2229+ "funding": {
2230+ "url": "https://github.com/sponsors/sindresorhus"
23992231 }
24002232 },
2401− "node_modules/npm/node_modules/clone": {
2402− "version": "1.0.4",
2403− "inBundle": true,
2404− "license": "MIT",
2233+ "node_modules/react": {
2234+ "version": "17.0.2",
2235+ "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
2236+ "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
2237+ "peer": true,
2238+ "dependencies": {
2239+ "loose-envify": "^1.1.0",
2240+ "object-assign": "^4.1.1"
2241+ },
24052242 "engines": {
2406− "node": ">=0.8"
2243+ "node": ">=0.10.0"
24072244 }
24082245 },
2409− "node_modules/npm/node_modules/cmd-shim": {
2410− "version": "4.1.0",
2411− "inBundle": true,
2412− "license": "ISC",
2246+ "node_modules/read-cache": {
2247+ "version": "1.0.0",
2248+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
2249+ "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
2250+ "dev": true,
24132251 "dependencies": {
2414− "mkdirp-infer-owner": "^2.0.0"
2415− },
2416− "engines": {
2417− "node": ">=10"
2252+ "pify": "^2.3.0"
24182253 }
24192254 },
2420− "node_modules/npm/node_modules/color-convert": {
2421− "version": "2.0.1",
2422− "inBundle": true,
2423− "license": "MIT",
2255+ "node_modules/readdirp": {
2256+ "version": "3.6.0",
2257+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
2258+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
2259+ "dev": true,
24242260 "dependencies": {
2425− "color-name": "~1.1.4"
2261+ "picomatch": "^2.2.1"
24262262 },
24272263 "engines": {
2428− "node": ">=7.0.0"
2264+ "node": ">=8.10.0"
24292265 }
24302266 },
2431− "node_modules/npm/node_modules/color-name": {
2432− "version": "1.1.4",
2433− "inBundle": true,
2434− "license": "MIT"
2435− },
2436− "node_modules/npm/node_modules/color-support": {
2437− "version": "1.1.3",
2438− "inBundle": true,
2439− "license": "ISC",
2440− "bin": {
2441− "color-support": "bin.js"
2442− }
2267+ "node_modules/regenerator-runtime": {
2268+ "version": "0.13.9",
2269+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
2270+ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
24432271 },
2444− "node_modules/npm/node_modules/colors": {
2445− "version": "1.4.0",
2446− "inBundle": true,
2447− "license": "MIT",
2448− "optional": true,
2272+ "node_modules/regexparam": {
2273+ "version": "2.0.0",
2274+ "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-2.0.0.tgz",
2275+ "integrity": "sha512-gJKwd2MVPWHAIFLsaYDZfyKzHNS4o7E/v8YmNf44vmeV2e4YfVoDToTOKTvE7ab68cRJ++kLuEXJBaEeJVt5ow==",
2276+ "dev": true,
24492277 "engines": {
2450− "node": ">=0.1.90"
2278+ "node": ">=8"
24512279 }
24522280 },
2453− "node_modules/npm/node_modules/columnify": {
2454− "version": "1.6.0",
2455− "inBundle": true,
2456− "license": "MIT",
2457− "dependencies": {
2458− "strip-ansi": "^6.0.1",
2459− "wcwidth": "^1.0.0"
2460− },
2281+ "node_modules/rename-keys": {
2282+ "version": "1.2.0",
2283+ "resolved": "https://registry.npmjs.org/rename-keys/-/rename-keys-1.2.0.tgz",
2284+ "integrity": "sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg==",
24612285 "engines": {
2462− "node": ">=8.0.0"
2286+ "node": ">= 0.8.0"
24632287 }
24642288 },
2465− "node_modules/npm/node_modules/common-ancestor-path": {
2466− "version": "1.0.1",
2467− "inBundle": true,
2468− "license": "ISC"
2469− },
2470− "node_modules/npm/node_modules/concat-map": {
2471− "version": "0.0.1",
2472− "inBundle": true,
2473− "license": "MIT"
2289+ "node_modules/require-directory": {
2290+ "version": "2.1.1",
2291+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
2292+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
2293+ "dev": true,
2294+ "engines": {
2295+ "node": ">=0.10.0"
2296+ }
24742297 },
2475− "node_modules/npm/node_modules/console-control-strings": {
2476− "version": "1.1.0",
2477− "inBundle": true,
2478− "license": "ISC"
2298+ "node_modules/require-relative": {
2299+ "version": "0.8.7",
2300+ "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz",
2301+ "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=",
2302+ "dev": true
24792303 },
2480− "node_modules/npm/node_modules/debug": {
2481− "version": "4.3.4",
2482− "inBundle": true,
2483− "license": "MIT",
2304+ "node_modules/resolve": {
2305+ "version": "1.21.0",
2306+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz",
2307+ "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==",
2308+ "dev": true,
24842309 "dependencies": {
2485− "ms": "2.1.2"
2310+ "is-core-module": "^2.8.0",
2311+ "path-parse": "^1.0.7",
2312+ "supports-preserve-symlinks-flag": "^1.0.0"
24862313 },
2487− "engines": {
2488− "node": ">=6.0"
2314+ "bin": {
2315+ "resolve": "bin/resolve"
24892316 },
2490− "peerDependenciesMeta": {
2491− "supports-color": {
2492− "optional": true
2493− }
2317+ "funding": {
2318+ "url": "https://github.com/sponsors/ljharb"
24942319 }
24952320 },
2496− "node_modules/npm/node_modules/debug/node_modules/ms": {
2497− "version": "2.1.2",
2498− "inBundle": true,
2499− "license": "MIT"
2500− },
2501− "node_modules/npm/node_modules/debuglog": {
2502− "version": "1.0.1",
2503− "inBundle": true,
2504− "license": "MIT",
2321+ "node_modules/resolve-from": {
2322+ "version": "4.0.0",
2323+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
2324+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
2325+ "dev": true,
25052326 "engines": {
2506− "node": "*"
2507− }
2508− },
2509− "node_modules/npm/node_modules/defaults": {
2510− "version": "1.0.3",
2511− "inBundle": true,
2512− "license": "MIT",
2513− "dependencies": {
2514− "clone": "^1.0.2"
2327+ "node": ">=4"
25152328 }
25162329 },
2517− "node_modules/npm/node_modules/delegates": {
2518− "version": "1.0.0",
2519− "inBundle": true,
2520− "license": "MIT"
2521− },
2522− "node_modules/npm/node_modules/depd": {
2523− "version": "1.1.2",
2524− "inBundle": true,
2525− "license": "MIT",
2330+ "node_modules/reusify": {
2331+ "version": "1.0.4",
2332+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
2333+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
2334+ "dev": true,
25262335 "engines": {
2527− "node": ">= 0.6"
2336+ "iojs": ">=1.0.0",
2337+ "node": ">=0.10.0"
25282338 }
25292339 },
2530− "node_modules/npm/node_modules/dezalgo": {
2531− "version": "1.0.3",
2532− "inBundle": true,
2533− "license": "ISC",
2340+ "node_modules/rimraf": {
2341+ "version": "2.7.1",
2342+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
2343+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
2344+ "dev": true,
25342345 "dependencies": {
2535− "asap": "^2.0.0",
2536− "wrappy": "1"
2346+ "glob": "^7.1.3"
2347+ },
2348+ "bin": {
2349+ "rimraf": "bin.js"
25372350 }
25382351 },
2539− "node_modules/npm/node_modules/diff": {
2540− "version": "5.0.0",
2541− "inBundle": true,
2542− "license": "BSD-3-Clause",
2352+ "node_modules/rollup": {
2353+ "version": "2.63.0",
2354+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.63.0.tgz",
2355+ "integrity": "sha512-nps0idjmD+NXl6OREfyYXMn/dar3WGcyKn+KBzPdaLecub3x/LrId0wUcthcr8oZUAcZAR8NKcfGGFlNgGL1kQ==",
2356+ "dev": true,
2357+ "bin": {
2358+ "rollup": "dist/bin/rollup"
2359+ },
25432360 "engines": {
2544− "node": ">=0.3.1"
2361+ "node": ">=10.0.0"
2362+ },
2363+ "optionalDependencies": {
2364+ "fsevents": "~2.3.2"
25452365 }
25462366 },
2547− "node_modules/npm/node_modules/emoji-regex": {
2548− "version": "8.0.0",
2549− "inBundle": true,
2550− "license": "MIT"
2551− },
2552− "node_modules/npm/node_modules/encoding": {
2553− "version": "0.1.13",
2554− "inBundle": true,
2555− "license": "MIT",
2556− "optional": true,
2367+ "node_modules/run-parallel": {
2368+ "version": "1.2.0",
2369+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
2370+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
2371+ "dev": true,
2372+ "funding": [
2373+ {
2374+ "type": "github",
2375+ "url": "https://github.com/sponsors/feross"
2376+ },
2377+ {
2378+ "type": "patreon",
2379+ "url": "https://www.patreon.com/feross"
2380+ },
2381+ {
2382+ "type": "consulting",
2383+ "url": "https://feross.org/support"
2384+ }
2385+ ],
25572386 "dependencies": {
2558− "iconv-lite": "^0.6.2"
2387+ "queue-microtask": "^1.2.2"
25592388 }
25602389 },
2561− "node_modules/npm/node_modules/env-paths": {
2562− "version": "2.2.1",
2563− "inBundle": true,
2564− "license": "MIT",
2390+ "node_modules/rxjs": {
2391+ "version": "6.6.7",
2392+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
2393+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
2394+ "dev": true,
2395+ "dependencies": {
2396+ "tslib": "^1.9.0"
2397+ },
25652398 "engines": {
2566− "node": ">=6"
2399+ "npm": ">=2.0.0"
25672400 }
25682401 },
2569− "node_modules/npm/node_modules/err-code": {
2570− "version": "2.0.3",
2571− "inBundle": true,
2572− "license": "MIT"
2573− },
2574− "node_modules/npm/node_modules/fastest-levenshtein": {
2575− "version": "1.0.12",
2576− "inBundle": true,
2577− "license": "MIT"
2402+ "node_modules/rxjs/node_modules/tslib": {
2403+ "version": "1.14.1",
2404+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
2405+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
2406+ "dev": true
25782407 },
2579− "node_modules/npm/node_modules/fs-minipass": {
2580− "version": "2.1.0",
2581− "inBundle": true,
2582− "license": "ISC",
2408+ "node_modules/sade": {
2409+ "version": "1.8.1",
2410+ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
2411+ "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
2412+ "dev": true,
25832413 "dependencies": {
2584− "minipass": "^3.0.0"
2414+ "mri": "^1.1.0"
25852415 },
25862416 "engines": {
2587− "node": ">= 8"
2417+ "node": ">=6"
25882418 }
25892419 },
2590− "node_modules/npm/node_modules/fs.realpath": {
2591− "version": "1.0.0",
2592− "inBundle": true,
2593− "license": "ISC"
2594− },
2595− "node_modules/npm/node_modules/function-bind": {
2596− "version": "1.1.1",
2597− "inBundle": true,
2598− "license": "MIT"
2599− },
2600− "node_modules/npm/node_modules/gauge": {
2601− "version": "4.0.4",
2602− "inBundle": true,
2603− "license": "ISC",
2420+ "node_modules/sander": {
2421+ "version": "0.5.1",
2422+ "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz",
2423+ "integrity": "sha1-dB4kXiMfB8r7b98PEzrfohalAq0=",
2424+ "dev": true,
26042425 "dependencies": {
2605− "aproba": "^1.0.3 || ^2.0.0",
2606− "color-support": "^1.1.3",
2607− "console-control-strings": "^1.1.0",
2608− "has-unicode": "^2.0.1",
2609− "signal-exit": "^3.0.7",
2610− "string-width": "^4.2.3",
2611− "strip-ansi": "^6.0.1",
2612− "wide-align": "^1.1.5"
2613− },
2614− "engines": {
2615− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2426+ "es6-promise": "^3.1.2",
2427+ "graceful-fs": "^4.1.3",
2428+ "mkdirp": "^0.5.1",
2429+ "rimraf": "^2.5.2"
26162430 }
26172431 },
2618− "node_modules/npm/node_modules/glob": {
2619− "version": "7.2.0",
2620− "inBundle": true,
2621− "license": "ISC",
2432+ "node_modules/sass": {
2433+ "version": "1.50.0",
2434+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz",
2435+ "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==",
2436+ "dev": true,
26222437 "dependencies": {
2623− "fs.realpath": "^1.0.0",
2624− "inflight": "^1.0.4",
2625− "inherits": "2",
2626− "minimatch": "^3.0.4",
2627− "once": "^1.3.0",
2628− "path-is-absolute": "^1.0.0"
2438+ "chokidar": ">=3.0.0 <4.0.0",
2439+ "immutable": "^4.0.0",
2440+ "source-map-js": ">=0.6.2 <2.0.0"
26292441 },
2630− "engines": {
2631− "node": "*"
2442+ "bin": {
2443+ "sass": "sass.js"
26322444 },
2633− "funding": {
2634− "url": "https://github.com/sponsors/isaacs"
2445+ "engines": {
2446+ "node": ">=12.0.0"
26352447 }
26362448 },
2637− "node_modules/npm/node_modules/graceful-fs": {
2638− "version": "4.2.9",
2639− "inBundle": true,
2640− "license": "ISC"
2641− },
2642− "node_modules/npm/node_modules/has": {
2643− "version": "1.0.3",
2644− "inBundle": true,
2645− "license": "MIT",
2449+ "node_modules/shebang-command": {
2450+ "version": "2.0.0",
2451+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
2452+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
2453+ "dev": true,
26462454 "dependencies": {
2647− "function-bind": "^1.1.1"
2455+ "shebang-regex": "^3.0.0"
26482456 },
26492457 "engines": {
2650− "node": ">= 0.4.0"
2458+ "node": ">=8"
26512459 }
26522460 },
2653− "node_modules/npm/node_modules/has-flag": {
2654− "version": "4.0.0",
2655− "inBundle": true,
2656− "license": "MIT",
2461+ "node_modules/shebang-regex": {
2462+ "version": "3.0.0",
2463+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
2464+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
2465+ "dev": true,
26572466 "engines": {
26582467 "node": ">=8"
26592468 }
26602469 },
2661− "node_modules/npm/node_modules/has-unicode": {
2662− "version": "2.0.1",
2663− "inBundle": true,
2664− "license": "ISC"
2665− },
2666− "node_modules/npm/node_modules/hosted-git-info": {
2667− "version": "5.0.0",
2668− "inBundle": true,
2669− "license": "ISC",
2470+ "node_modules/sigma-jh": {
2471+ "version": "2.4.2",
2472+ "resolved": "https://registry.npmjs.org/sigma-jh/-/sigma-jh-2.4.2.tgz",
2473+ "integrity": "sha512-viB4M5Y79N5rAgs0z3M4Gff4HX53S+UMwblPDEH/Nkwwe7AcmcWwsEYsGv/xL/TNQzLIBBb0NaNAg5ZhnbEm8g==",
26702474 "dependencies": {
2671− "lru-cache": "^7.5.1"
2672− },
2673− "engines": {
2674− "node": "^12.13.0 || ^14.15.0 || >=16"
2475+ "@yomguithereal/helpers": "^1.1.1",
2476+ "events": "^3.3.0",
2477+ "graphology-utils": "^2.5.0"
26752478 }
26762479 },
2677− "node_modules/npm/node_modules/http-cache-semantics": {
2678− "version": "4.1.0",
2679− "inBundle": true,
2680− "license": "BSD-2-Clause"
2681− },
2682− "node_modules/npm/node_modules/http-proxy-agent": {
2683− "version": "5.0.0",
2684− "inBundle": true,
2685− "license": "MIT",
2686− "dependencies": {
2687− "@tootallnate/once": "2",
2688− "agent-base": "6",
2689− "debug": "4"
2690− },
2480+ "node_modules/slash": {
2481+ "version": "4.0.0",
2482+ "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
2483+ "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
2484+ "dev": true,
26912485 "engines": {
2692− "node": ">= 6"
2486+ "node": ">=12"
2487+ },
2488+ "funding": {
2489+ "url": "https://github.com/sponsors/sindresorhus"
26932490 }
26942491 },
2695− "node_modules/npm/node_modules/https-proxy-agent": {
2696− "version": "5.0.0",
2697− "inBundle": true,
2698− "license": "MIT",
2492+ "node_modules/sorcery": {
2493+ "version": "0.10.0",
2494+ "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz",
2495+ "integrity": "sha1-iukK19fLBfxZ8asMY3hF1cFaUrc=",
2496+ "dev": true,
26992497 "dependencies": {
2700− "agent-base": "6",
2701− "debug": "4"
2498+ "buffer-crc32": "^0.2.5",
2499+ "minimist": "^1.2.0",
2500+ "sander": "^0.5.0",
2501+ "sourcemap-codec": "^1.3.0"
27022502 },
2703− "engines": {
2704− "node": ">= 6"
2503+ "bin": {
2504+ "sorcery": "bin/index.js"
27052505 }
27062506 },
2707− "node_modules/npm/node_modules/humanize-ms": {
2708− "version": "1.2.1",
2709− "inBundle": true,
2710− "license": "MIT",
2711− "dependencies": {
2712− "ms": "^2.0.0"
2507+ "node_modules/source-map": {
2508+ "version": "0.7.3",
2509+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
2510+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
2511+ "dev": true,
2512+ "engines": {
2513+ "node": ">= 8"
27132514 }
27142515 },
2715− "node_modules/npm/node_modules/iconv-lite": {
2716− "version": "0.6.3",
2717− "inBundle": true,
2718− "license": "MIT",
2719− "optional": true,
2720− "dependencies": {
2721− "safer-buffer": ">= 2.1.2 < 3.0.0"
2722− },
2516+ "node_modules/source-map-js": {
2517+ "version": "1.0.1",
2518+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
2519+ "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
2520+ "dev": true,
27232521 "engines": {
27242522 "node": ">=0.10.0"
27252523 }
27262524 },
2727− "node_modules/npm/node_modules/ignore-walk": {
2728− "version": "4.0.1",
2729− "inBundle": true,
2730− "license": "ISC",
2731− "dependencies": {
2732− "minimatch": "^3.0.4"
2733− },
2734− "engines": {
2735− "node": ">=10"
2736− }
2525+ "node_modules/sourcemap-codec": {
2526+ "version": "1.4.8",
2527+ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
2528+ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
2529+ "dev": true
27372530 },
2738− "node_modules/npm/node_modules/imurmurhash": {
2739− "version": "0.1.4",
2740− "inBundle": true,
2741− "license": "MIT",
2742− "engines": {
2743− "node": ">=0.8.19"
2744− }
2531+ "node_modules/spawn-command": {
2532+ "version": "0.0.2-1",
2533+ "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
2534+ "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=",
2535+ "dev": true
27452536 },
2746− "node_modules/npm/node_modules/indent-string": {
2747− "version": "4.0.0",
2748− "inBundle": true,
2749− "license": "MIT",
2537+ "node_modules/string-width": {
2538+ "version": "4.2.3",
2539+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2540+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2541+ "dev": true,
2542+ "dependencies": {
2543+ "emoji-regex": "^8.0.0",
2544+ "is-fullwidth-code-point": "^3.0.0",
2545+ "strip-ansi": "^6.0.1"
2546+ },
27502547 "engines": {
27512548 "node": ">=8"
27522549 }
27532550 },
2754− "node_modules/npm/node_modules/infer-owner": {
2755− "version": "1.0.4",
2756− "inBundle": true,
2757− "license": "ISC"
2758− },
2759− "node_modules/npm/node_modules/inflight": {
2760− "version": "1.0.6",
2761− "inBundle": true,
2762− "license": "ISC",
2551+ "node_modules/strip-ansi": {
2552+ "version": "6.0.1",
2553+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2554+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2555+ "dev": true,
27632556 "dependencies": {
2764− "once": "^1.3.0",
2765− "wrappy": "1"
2766− }
2767− },
2768− "node_modules/npm/node_modules/inherits": {
2769− "version": "2.0.4",
2770− "inBundle": true,
2771− "license": "ISC"
2772− },
2773− "node_modules/npm/node_modules/ini": {
2774− "version": "2.0.0",
2775− "inBundle": true,
2776− "license": "ISC",
2557+ "ansi-regex": "^5.0.1"
2558+ },
27772559 "engines": {
2778− "node": ">=10"
2560+ "node": ">=8"
27792561 }
27802562 },
2781− "node_modules/npm/node_modules/init-package-json": {
2782− "version": "3.0.2",
2783− "inBundle": true,
2784− "license": "ISC",
2563+ "node_modules/strip-indent": {
2564+ "version": "3.0.0",
2565+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
2566+ "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
2567+ "dev": true,
27852568 "dependencies": {
2786− "npm-package-arg": "^9.0.1",
2787− "promzard": "^0.3.0",
2788− "read": "^1.0.7",
2789− "read-package-json": "^5.0.0",
2790− "semver": "^7.3.5",
2791− "validate-npm-package-license": "^3.0.4",
2792− "validate-npm-package-name": "^4.0.0"
2569+ "min-indent": "^1.0.0"
27932570 },
2794− "engines": {
2795− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2796− }
2797− },
2798− "node_modules/npm/node_modules/ip": {
2799− "version": "1.1.5",
2800− "inBundle": true,
2801− "license": "MIT"
2802− },
2803− "node_modules/npm/node_modules/ip-regex": {
2804− "version": "4.3.0",
2805− "inBundle": true,
2806− "license": "MIT",
28072571 "engines": {
28082572 "node": ">=8"
28092573 }
28102574 },
2811− "node_modules/npm/node_modules/is-cidr": {
2812− "version": "4.0.2",
2813− "inBundle": true,
2814− "license": "BSD-2-Clause",
2575+ "node_modules/supports-color": {
2576+ "version": "7.2.0",
2577+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
2578+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
2579+ "dev": true,
28152580 "dependencies": {
2816− "cidr-regex": "^3.1.1"
2581+ "has-flag": "^4.0.0"
28172582 },
28182583 "engines": {
2819− "node": ">=10"
2584+ "node": ">=8"
28202585 }
28212586 },
2822− "node_modules/npm/node_modules/is-core-module": {
2823− "version": "2.8.1",
2824− "inBundle": true,
2825− "license": "MIT",
2826− "dependencies": {
2827− "has": "^1.0.3"
2587+ "node_modules/supports-preserve-symlinks-flag": {
2588+ "version": "1.0.0",
2589+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
2590+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
2591+ "dev": true,
2592+ "engines": {
2593+ "node": ">= 0.4"
28282594 },
28292595 "funding": {
28302596 "url": "https://github.com/sponsors/ljharb"
28312597 }
28322598 },
2833− "node_modules/npm/node_modules/is-fullwidth-code-point": {
2834− "version": "3.0.0",
2835− "inBundle": true,
2836− "license": "MIT",
2599+ "node_modules/svelte": {
2600+ "version": "3.48.0",
2601+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.48.0.tgz",
2602+ "integrity": "sha512-fN2YRm/bGumvjUpu6yI3BpvZnpIm9I6A7HR4oUNYd7ggYyIwSA/BX7DJ+UXXffLp6XNcUijyLvttbPVCYa/3xQ==",
28372603 "engines": {
2838− "node": ">=8"
2839− }
2840− },
2841− "node_modules/npm/node_modules/is-lambda": {
2842− "version": "1.0.1",
2843− "inBundle": true,
2844− "license": "MIT"
2845− },
2846− "node_modules/npm/node_modules/isexe": {
2847− "version": "2.0.0",
2848− "inBundle": true,
2849− "license": "ISC"
2850− },
2851− "node_modules/npm/node_modules/json-parse-even-better-errors": {
2852− "version": "2.3.1",
2853− "inBundle": true,
2854− "license": "MIT"
2855− },
2856− "node_modules/npm/node_modules/json-stringify-nice": {
2857− "version": "1.1.4",
2858− "inBundle": true,
2859− "license": "ISC",
2860− "funding": {
2861− "url": "https://github.com/sponsors/isaacs"
2604+ "node": ">= 8"
28622605 }
28632606 },
2864− "node_modules/npm/node_modules/jsonparse": {
2865− "version": "1.3.1",
2866− "engines": [
2867− "node >= 0.2.0"
2868− ],
2869− "inBundle": true,
2870− "license": "MIT"
2871− },
2872− "node_modules/npm/node_modules/just-diff": {
2873− "version": "5.0.1",
2874− "inBundle": true,
2875− "license": "MIT"
2876− },
2877− "node_modules/npm/node_modules/just-diff-apply": {
2878− "version": "5.2.0",
2879− "inBundle": true,
2880− "license": "MIT"
2881− },
2882− "node_modules/npm/node_modules/libnpmaccess": {
2883− "version": "6.0.2",
2884− "inBundle": true,
2885− "license": "ISC",
2607+ "node_modules/svelte-check": {
2608+ "version": "2.2.11",
2609+ "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-2.2.11.tgz",
2610+ "integrity": "sha512-clotPGGZPj3LuS9qP1lk+Wwnsj+js42ehCPmHk+qtyaQh/dU95e0qkpPmtmOMYHN6My5Y75XqeN1QNLj5V5gwA==",
2611+ "dev": true,
28862612 "dependencies": {
2887− "aproba": "^2.0.0",
2888− "minipass": "^3.1.1",
2889− "npm-package-arg": "^9.0.1",
2890− "npm-registry-fetch": "^13.0.0"
2613+ "chalk": "^4.0.0",
2614+ "chokidar": "^3.4.1",
2615+ "fast-glob": "^3.2.7",
2616+ "import-fresh": "^3.2.1",
2617+ "minimist": "^1.2.5",
2618+ "sade": "^1.7.4",
2619+ "source-map": "^0.7.3",
2620+ "svelte-preprocess": "^4.0.0",
2621+ "typescript": "*"
28912622 },
2892− "engines": {
2893− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2894− }
2895− },
2896− "node_modules/npm/node_modules/libnpmdiff": {
2897− "version": "4.0.2",
2898− "inBundle": true,
2899− "license": "ISC",
2900− "dependencies": {
2901− "@npmcli/disparity-colors": "^1.0.1",
2902− "@npmcli/installed-package-contents": "^1.0.7",
2903− "binary-extensions": "^2.2.0",
2904− "diff": "^5.0.0",
2905− "minimatch": "^3.0.4",
2906− "npm-package-arg": "^9.0.1",
2907− "pacote": "^13.0.5",
2908− "tar": "^6.1.0"
2623+ "bin": {
2624+ "svelte-check": "bin/svelte-check"
29092625 },
2910− "engines": {
2911− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2626+ "peerDependencies": {
2627+ "svelte": "^3.24.0"
29122628 }
29132629 },
2914− "node_modules/npm/node_modules/libnpmexec": {
2915− "version": "4.0.2",
2916− "inBundle": true,
2917− "license": "ISC",
2918− "dependencies": {
2919− "@npmcli/arborist": "^5.0.0",
2920− "@npmcli/ci-detect": "^2.0.0",
2921− "@npmcli/run-script": "^3.0.0",
2922− "chalk": "^4.1.0",
2923− "mkdirp-infer-owner": "^2.0.0",
2924− "npm-package-arg": "^9.0.1",
2925− "npmlog": "^6.0.1",
2926− "pacote": "^13.0.5",
2927− "proc-log": "^2.0.0",
2928− "read": "^1.0.7",
2929− "read-package-json-fast": "^2.0.2",
2930− "walk-up-path": "^1.0.0"
2931− },
2932− "engines": {
2933− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2934− }
2630+ "node_modules/svelte-copy-to-clipboard": {
2631+ "version": "0.2.5",
2632+ "resolved": "https://registry.npmjs.org/svelte-copy-to-clipboard/-/svelte-copy-to-clipboard-0.2.5.tgz",
2633+ "integrity": "sha512-EAULxib4pRa59nyz25dDKITgSAVkrNVojRZVCSO8MIFd5GJljghJaCTIe/7R+O3GxKYIwJ3XHDNoY1hfjJeyEg=="
29352634 },
2936− "node_modules/npm/node_modules/libnpmfund": {
2937− "version": "3.0.1",
2938− "inBundle": true,
2939− "license": "ISC",
2940− "dependencies": {
2941− "@npmcli/arborist": "^5.0.0"
2942− },
2943− "engines": {
2944− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2635+ "node_modules/svelte-hmr": {
2636+ "version": "0.14.9",
2637+ "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.14.9.tgz",
2638+ "integrity": "sha512-bKE9+4qb4sAnA+TKHiYurUl970rjA0XmlP9TEP7K/ncyWz3m81kA4HOgmlZK/7irGK7gzZlaPDI3cmf8fp/+tg==",
2639+ "dev": true,
2640+ "peerDependencies": {
2641+ "svelte": ">=3.19.0"
29452642 }
29462643 },
2947− "node_modules/npm/node_modules/libnpmhook": {
2948− "version": "8.0.2",
2949− "inBundle": true,
2950− "license": "ISC",
2644+ "node_modules/svelte-markdown": {
2645+ "version": "0.2.3",
2646+ "resolved": "https://registry.npmjs.org/svelte-markdown/-/svelte-markdown-0.2.3.tgz",
2647+ "integrity": "sha512-2h680NzTXnAD0CXhxe3GeHl6W+ayG4iKQRl+BIDRw+R0mUE0OiNxP1Vt8Rn+aWevB/LBiBIPCAwvL+0BkG057A==",
29512648 "dependencies": {
2952− "aproba": "^2.0.0",
2953− "npm-registry-fetch": "^13.0.0"
2649+ "@types/marked": "^4.0.1",
2650+ "marked": "^4.0.10"
29542651 },
2955− "engines": {
2956− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2652+ "peerDependencies": {
2653+ "svelte": "^3.0.0"
29572654 }
29582655 },
2959− "node_modules/npm/node_modules/libnpmorg": {
2960− "version": "4.0.2",
2961− "inBundle": true,
2962− "license": "ISC",
2656+ "node_modules/svelte-preprocess": {
2657+ "version": "4.10.1",
2658+ "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.10.1.tgz",
2659+ "integrity": "sha512-NSNloaylf+o9UeyUR2KvpdxrAyMdHl3U7rMnoP06/sG0iwJvlUM4TpMno13RaNqovh4AAoGsx1jeYcIyuGUXMw==",
2660+ "dev": true,
2661+ "hasInstallScript": true,
29632662 "dependencies": {
2964− "aproba": "^2.0.0",
2965− "npm-registry-fetch": "^13.0.0"
2663+ "@types/pug": "^2.0.4",
2664+ "@types/sass": "^1.16.0",
2665+ "detect-indent": "^6.0.0",
2666+ "magic-string": "^0.25.7",
2667+ "sorcery": "^0.10.0",
2668+ "strip-indent": "^3.0.0"
29662669 },
29672670 "engines": {
2968− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2969− }
2970− },
2971− "node_modules/npm/node_modules/libnpmpack": {
2972− "version": "4.0.2",
2973− "inBundle": true,
2974− "license": "ISC",
2975− "dependencies": {
2976− "@npmcli/run-script": "^3.0.0",
2977− "npm-package-arg": "^9.0.1",
2978− "pacote": "^13.0.5"
2671+ "node": ">= 9.11.2"
29792672 },
2980− "engines": {
2981− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2673+ "peerDependencies": {
2674+ "@babel/core": "^7.10.2",
2675+ "coffeescript": "^2.5.1",
2676+ "less": "^3.11.3",
2677+ "postcss": "^7 || ^8",
2678+ "postcss-load-config": "^2.1.0 || ^3.0.0",
2679+ "pug": "^3.0.0",
2680+ "sass": "^1.26.8",
2681+ "stylus": "^0.54.7",
2682+ "sugarss": "^2.0.0",
2683+ "svelte": "^3.23.0",
2684+ "typescript": "^4.5.2"
2685+ },
2686+ "peerDependenciesMeta": {
2687+ "@babel/core": {
2688+ "optional": true
2689+ },
2690+ "coffeescript": {
2691+ "optional": true
2692+ },
2693+ "less": {
2694+ "optional": true
2695+ },
2696+ "node-sass": {
2697+ "optional": true
2698+ },
2699+ "postcss": {
2700+ "optional": true
2701+ },
2702+ "postcss-load-config": {
2703+ "optional": true
2704+ },
2705+ "pug": {
2706+ "optional": true
2707+ },
2708+ "sass": {
2709+ "optional": true
2710+ },
2711+ "stylus": {
2712+ "optional": true
2713+ },
2714+ "sugarss": {
2715+ "optional": true
2716+ },
2717+ "typescript": {
2718+ "optional": true
2719+ }
29822720 }
29832721 },
2984− "node_modules/npm/node_modules/libnpmpublish": {
2985− "version": "6.0.2",
2986− "inBundle": true,
2987− "license": "ISC",
2722+ "node_modules/svelte-spa-router": {
2723+ "version": "3.2.0",
2724+ "resolved": "https://registry.npmjs.org/svelte-spa-router/-/svelte-spa-router-3.2.0.tgz",
2725+ "integrity": "sha512-igemo5Vs82TGBBw+DjWt6qKameXYzNs6aDXcTxou5XbEvOjiRcAM6MLkdVRCatn6u8r42dE99bt/br7T4qe/AQ==",
2726+ "dev": true,
29882727 "dependencies": {
2989− "normalize-package-data": "^4.0.0",
2990− "npm-package-arg": "^9.0.1",
2991− "npm-registry-fetch": "^13.0.0",
2992− "semver": "^7.1.3",
2993− "ssri": "^8.0.1"
2728+ "regexparam": "2.0.0"
29942729 },
2995− "engines": {
2996− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2730+ "funding": {
2731+ "url": "https://github.com/sponsors/ItalyPaleAle"
29972732 }
29982733 },
2999− "node_modules/npm/node_modules/libnpmsearch": {
3000− "version": "5.0.2",
3001− "inBundle": true,
3002− "license": "ISC",
2734+ "node_modules/svgson": {
2735+ "version": "4.1.0",
2736+ "resolved": "https://registry.npmjs.org/svgson/-/svgson-4.1.0.tgz",
2737+ "integrity": "sha512-DodISxHtdLKUghDYA+PGK4Qq350+CbBAkdvGLkBFSmWd9WKSg4dijgjB1IiRPTmsUCd+a7KYe+ILHtklYgQyzQ==",
30032738 "dependencies": {
3004− "npm-registry-fetch": "^13.0.0"
3005− },
3006− "engines": {
3007− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2739+ "deep-rename-keys": "^0.2.1",
2740+ "omit-deep": "0.3.0",
2741+ "xml-reader": "2.4.3"
30082742 }
30092743 },
3010− "node_modules/npm/node_modules/libnpmteam": {
3011− "version": "4.0.2",
3012− "inBundle": true,
3013− "license": "ISC",
2744+ "node_modules/tailwindcss": {
2745+ "version": "3.0.12",
2746+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.12.tgz",
2747+ "integrity": "sha512-VqhF86z2c34sJyS5ZS8Q2nYuN0KzqZw1GGsuQQO9kJ3mY1oG7Fsag0vICkxUVXk6P+1sUkTkjMjKWCjEF0hNHw==",
2748+ "dev": true,
30142749 "dependencies": {
3015− "aproba": "^2.0.0",
3016− "npm-registry-fetch": "^13.0.0"
2750+ "arg": "^5.0.1",
2751+ "chalk": "^4.1.2",
2752+ "chokidar": "^3.5.2",
2753+ "color-name": "^1.1.4",
2754+ "cosmiconfig": "^7.0.1",
2755+ "detective": "^5.2.0",
2756+ "didyoumean": "^1.2.2",
2757+ "dlv": "^1.1.3",
2758+ "fast-glob": "^3.2.7",
2759+ "glob-parent": "^6.0.2",
2760+ "is-glob": "^4.0.3",
2761+ "normalize-path": "^3.0.0",
2762+ "object-hash": "^2.2.0",
2763+ "postcss-js": "^4.0.0",
2764+ "postcss-load-config": "^3.1.0",
2765+ "postcss-nested": "5.0.6",
2766+ "postcss-selector-parser": "^6.0.8",
2767+ "postcss-value-parser": "^4.2.0",
2768+ "quick-lru": "^5.1.1",
2769+ "resolve": "^1.20.0"
30172770 },
3018− "engines": {
3019− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
3020− }
3021− },
3022− "node_modules/npm/node_modules/libnpmversion": {
3023− "version": "3.0.1",
3024− "inBundle": true,
3025− "license": "ISC",
3026− "dependencies": {
3027− "@npmcli/git": "^3.0.0",
3028− "@npmcli/run-script": "^3.0.0",
3029− "json-parse-even-better-errors": "^2.3.1",
3030− "proc-log": "^2.0.0",
3031− "semver": "^7.3.5",
3032− "stringify-package": "^1.0.1"
2771+ "bin": {
2772+ "tailwind": "lib/cli.js",
2773+ "tailwindcss": "lib/cli.js"
30332774 },
30342775 "engines": {
3035− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
3036− }
3037− },
3038− "node_modules/npm/node_modules/lru-cache": {
3039− "version": "7.7.1",
3040− "inBundle": true,
3041− "license": "ISC",
3042− "engines": {
3043− "node": ">=12"
3044− }
3045− },
3046− "node_modules/npm/node_modules/make-fetch-happen": {
3047− "version": "10.1.1",
3048− "inBundle": true,
3049− "license": "ISC",
3050− "dependencies": {
3051− "agentkeepalive": "^4.2.1",
3052− "cacache": "^16.0.2",
3053− "http-cache-semantics": "^4.1.0",
3054− "http-proxy-agent": "^5.0.0",
3055− "https-proxy-agent": "^5.0.0",
3056− "is-lambda": "^1.0.1",
3057− "lru-cache": "^7.7.1",
3058− "minipass": "^3.1.6",
3059− "minipass-collect": "^1.0.2",
3060− "minipass-fetch": "^2.0.3",
3061− "minipass-flush": "^1.0.5",
3062− "minipass-pipeline": "^1.2.4",
3063− "negotiator": "^0.6.3",
3064− "promise-retry": "^2.0.1",
3065− "socks-proxy-agent": "^6.1.1",
3066− "ssri": "^8.0.1"
3067− },
3068− "engines": {
3069− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
3070− }
3071− },
3072− "node_modules/npm/node_modules/minimatch": {
3073− "version": "3.1.2",
3074− "inBundle": true,
3075− "license": "ISC",
3076− "dependencies": {
3077− "brace-expansion": "^1.1.7"
2776+ "node": ">=12.13.0"
30782777 },
3079− "engines": {
3080− "node": "*"
2778+ "peerDependencies": {
2779+ "autoprefixer": "^10.0.2",
2780+ "postcss": "^8.0.9"
30812781 }
30822782 },
3083− "node_modules/npm/node_modules/minipass": {
3084− "version": "3.1.6",
3085− "inBundle": true,
3086− "license": "ISC",
2783+ "node_modules/tailwindcss/node_modules/glob-parent": {
2784+ "version": "6.0.2",
2785+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
2786+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
2787+ "dev": true,
30872788 "dependencies": {
3088− "yallist": "^4.0.0"
2789+ "is-glob": "^4.0.3"
30892790 },
30902791 "engines": {
3091− "node": ">=8"
2792+ "node": ">=10.13.0"
30922793 }
30932794 },
3094− "node_modules/npm/node_modules/minipass-collect": {
3095− "version": "1.0.2",
3096− "inBundle": true,
3097− "license": "ISC",
3098− "dependencies": {
3099− "minipass": "^3.0.0"
3100− },
3101− "engines": {
3102− "node": ">= 8"
3103− }
2795+ "node_modules/thenby": {
2796+ "version": "1.3.4",
2797+ "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz",
2798+ "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==",
2799+ "dev": true
31042800 },
3105− "node_modules/npm/node_modules/minipass-fetch": {
3106− "version": "2.1.0",
3107− "inBundle": true,
3108− "license": "MIT",
2801+ "node_modules/tippy.js": {
2802+ "version": "6.3.7",
2803+ "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
2804+ "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
31092805 "dependencies": {
3110− "minipass": "^3.1.6",
3111− "minipass-sized": "^1.0.3",
3112− "minizlib": "^2.1.2"
3113− },
3114− "engines": {
3115− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
3116− },
3117− "optionalDependencies": {
3118− "encoding": "^0.1.13"
2806+ "@popperjs/core": "^2.9.0"
31192807 }
31202808 },
3121− "node_modules/npm/node_modules/minipass-flush": {
3122− "version": "1.0.5",
3123− "inBundle": true,
3124− "license": "ISC",
2809+ "node_modules/to-regex-range": {
2810+ "version": "5.0.1",
2811+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2812+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2813+ "dev": true,
31252814 "dependencies": {
3126− "minipass": "^3.0.0"
2815+ "is-number": "^7.0.0"
31272816 },
31282817 "engines": {
3129− "node": ">= 8"
2818+ "node": ">=8.0"
31302819 }
31312820 },
3132− "node_modules/npm/node_modules/minipass-json-stream": {
3133− "version": "1.0.1",
3134− "inBundle": true,
3135− "license": "MIT",
3136− "dependencies": {
3137− "jsonparse": "^1.3.1",
3138− "minipass": "^3.0.0"
3139− }
2821+ "node_modules/transformation-matrix": {
2822+ "version": "2.1.1",
2823+ "resolved": "https://registry.npmjs.org/transformation-matrix/-/transformation-matrix-2.1.1.tgz",
2824+ "integrity": "sha512-74MoNHhwLVuzwaPDcAecFjSkOA9vwWqyOdkeB0Be8Jc/IWSS5SNZKapFllqzkTliqZptkvqX5CZnVeDvfhN8cw=="
31402825 },
3141− "node_modules/npm/node_modules/minipass-pipeline": {
3142− "version": "1.2.4",
3143− "inBundle": true,
3144− "license": "ISC",
3145− "dependencies": {
3146− "minipass": "^3.0.0"
3147− },
3148− "engines": {
3149− "node": ">=8"
2826+ "node_modules/tree-kill": {
2827+ "version": "1.2.2",
2828+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
2829+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
2830+ "dev": true,
2831+ "bin": {
2832+ "tree-kill": "cli.js"
31502833 }
31512834 },
3152− "node_modules/npm/node_modules/minipass-sized": {
3153− "version": "1.0.3",
3154− "inBundle": true,
3155− "license": "ISC",
3156− "dependencies": {
3157− "minipass": "^3.0.0"
3158− },
3159− "engines": {
3160− "node": ">=8"
3161− }
2835+ "node_modules/tslib": {
2836+ "version": "2.3.1",
2837+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
2838+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
2839+ "dev": true
31622840 },
3163− "node_modules/npm/node_modules/minizlib": {
3164− "version": "2.1.2",
3165− "inBundle": true,
3166− "license": "MIT",
3167− "dependencies": {
3168− "minipass": "^3.0.0",
3169− "yallist": "^4.0.0"
2841+ "node_modules/typescript": {
2842+ "version": "4.5.4",
2843+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
2844+ "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
2845+ "dev": true,
2846+ "bin": {
2847+ "tsc": "bin/tsc",
2848+ "tsserver": "bin/tsserver"
31702849 },
31712850 "engines": {
3172− "node": ">= 8"
2851+ "node": ">=4.2.0"
31732852 }
31742853 },
3175− "node_modules/npm/node_modules/mkdirp": {
3176− "version": "1.0.4",
3177− "inBundle": true,
3178− "license": "MIT",
3179− "bin": {
3180− "mkdirp": "bin/cmd.js"
3181− },
2854+ "node_modules/universalify": {
2855+ "version": "2.0.0",
2856+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
2857+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
2858+ "dev": true,
31822859 "engines": {
3183− "node": ">=10"
2860+ "node": ">= 10.0.0"
31842861 }
31852862 },
3186− "node_modules/npm/node_modules/mkdirp-infer-owner": {
3187− "version": "2.0.0",
3188− "inBundle": true,
3189− "license": "ISC",
2863+ "node_modules/unset-value": {
2864+ "version": "0.1.2",
2865+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz",
2866+ "integrity": "sha512-yhv5I4TsldLdE3UcVQn0hD2T5sNCPv4+qm/CTUpRKIpwthYRIipsAPdsrNpOI79hPQa0rTTeW22Fq6JWRcTgNg==",
31902867 "dependencies": {
3191− "chownr": "^2.0.0",
3192− "infer-owner": "^1.0.4",
3193− "mkdirp": "^1.0.3"
2868+ "has-value": "^0.3.1",
2869+ "isobject": "^3.0.0"
31942870 },
31952871 "engines": {
3196− "node": ">=10"
2872+ "node": ">=0.10.0"
31972873 }
31982874 },
3199− "node_modules/npm/node_modules/ms": {
3200− "version": "2.1.3",
3201− "inBundle": true,
3202− "license": "MIT"
2875+ "node_modules/urbit-ob": {
2876+ "version": "5.0.1",
2877+ "resolved": "https://registry.npmjs.org/urbit-ob/-/urbit-ob-5.0.1.tgz",
2878+ "integrity": "sha512-qGNAwu87XNkW3g8ah4fUwmh2EKXtsdhEbyEiE5qX4Op17rhLH3HSkvu8g9z+MhqX51Uz9sf8ktvqJj/IRwETIQ==",
2879+ "dependencies": {
2880+ "bn.js": "^4.11.8",
2881+ "lodash.chunk": "^4.2.0",
2882+ "lodash.isequal": "^4.5.0"
2883+ }
32032884 },
3204− "node_modules/npm/node_modules/mute-stream": {
3205− "version": "0.0.8",
3206− "inBundle": true,
3207− "license": "ISC"
2885+ "node_modules/urbit-ob/node_modules/bn.js": {
2886+ "version": "4.12.0",
2887+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
2888+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
32082889 },
3209− "node_modules/npm/node_modules/negotiator": {
3210− "version": "0.6.3",
3211− "inBundle": true,
3212− "license": "MIT",
3213− "engines": {
3214− "node": ">= 0.6"
3215− }
2890+ "node_modules/util-deprecate": {
2891+ "version": "1.0.2",
2892+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2893+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
2894+ "dev": true
32162895 },
3217− "node_modules/npm/node_modules/node-gyp": {
3218− "version": "9.0.0",
3219− "inBundle": true,
3220− "license": "MIT",
2896+ "node_modules/vite": {
2897+ "version": "2.7.10",
2898+ "resolved": "https://registry.npmjs.org/vite/-/vite-2.7.10.tgz",
2899+ "integrity": "sha512-KEY96ntXUid1/xJihJbgmLZx7QSC2D4Tui0FdS0Old5OokYzFclcofhtxtjDdGOk/fFpPbHv9yw88+rB93Tb8w==",
2900+ "dev": true,
32212901 "dependencies": {
3222− "env-paths": "^2.2.0",
3223− "glob": "^7.1.4",
3224− "graceful-fs": "^4.2.6",
3225− "make-fetch-happen": "^10.0.3",
3226− "nopt": "^5.0.0",
3227− "npmlog": "^6.0.0",
3228− "rimraf": "^3.0.2",
3229− "semver": "^7.3.5",
3230− "tar": "^6.1.2",
3231− "which": "^2.0.2"
2902+ "esbuild": "^0.13.12",
2903+ "postcss": "^8.4.5",
2904+ "resolve": "^1.20.0",
2905+ "rollup": "^2.59.0"
32322906 },
32332907 "bin": {
3234− "node-gyp": "bin/node-gyp.js"
2908+ "vite": "bin/vite.js"
32352909 },
32362910 "engines": {
3237− "node": "^12.22 || ^14.13 || >=16"
3238− }
3239− },
3240− "node_modules/npm/node_modules/nopt": {
3241− "version": "5.0.0",
3242− "inBundle": true,
3243− "license": "ISC",
3244− "dependencies": {
3245− "abbrev": "1"
2911+ "node": ">=12.2.0"
32462912 },
3247− "bin": {
3248− "nopt": "bin/nopt.js"
2913+ "optionalDependencies": {
2914+ "fsevents": "~2.3.2"
32492915 },
3250− "engines": {
3251− "node": ">=6"
3252− }
3253− },
3254− "node_modules/npm/node_modules/normalize-package-data": {
3255− "version": "4.0.0",
3256− "inBundle": true,
3257− "license": "BSD-2-Clause",
3258− "dependencies": {
3259− "hosted-git-info": "^5.0.0",
3260− "is-core-module": "^2.8.1",
3261− "semver": "^7.3.5",
3262− "validate-npm-package-license": "^3.0.4"
2916+ "peerDependencies": {
2917+ "less": "*",
2918+ "sass": "*",
2919+ "stylus": "*"
32632920 },
3264− "engines": {
3265− "node": "^12.13.0 || ^14.15.0 || >=16"
2921+ "peerDependenciesMeta": {
2922+ "less": {
2923+ "optional": true
2924+ },
2925+ "sass": {
2926+ "optional": true
2927+ },
2928+ "stylus": {
2929+ "optional": true
2930+ }
32662931 }
32672932 },
3268− "node_modules/npm/node_modules/npm-audit-report": {
3269− "version": "3.0.0",
3270− "inBundle": true,
3271− "license": "ISC",
3272− "dependencies": {
3273− "chalk": "^4.0.0"
3274− },
2933+ "node_modules/vite-plugin-html-config": {
2934+ "version": "1.0.8",
2935+ "resolved": "https://registry.npmjs.org/vite-plugin-html-config/-/vite-plugin-html-config-1.0.8.tgz",
2936+ "integrity": "sha512-3tTtBQO+6zpC8uzAAfj3FWygj+V6H6F9fEt5KtB3j5UHsRYP0yLpTHsMvubXtqCXbKDp1oOakYYSjprqYcbrpA==",
2937+ "dev": true,
32752938 "engines": {
3276− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
3277− }
3278− },
3279− "node_modules/npm/node_modules/npm-bundled": {
3280− "version": "1.1.2",
3281− "inBundle": true,
3282− "license": "ISC",
3283− "dependencies": {
3284− "npm-normalize-package-bin": "^1.0.1"
3285− }
3286− },
3287− "node_modules/npm/node_modules/npm-install-checks": {
3288− "version": "4.0.0",
3289− "inBundle": true,
3290− "license": "BSD-2-Clause",
3291− "dependencies": {
3292− "semver": "^7.1.1"
2939+ "node": ">=12.0.0"
32932940 },
3294− "engines": {
3295− "node": ">=10"
2941+ "peerDependencies": {
2942+ "vite": "^2.0.5"
32962943 }
32972944 },
3298− "node_modules/npm/node_modules/npm-normalize-package-bin": {
3299− "version": "1.0.1",
3300− "inBundle": true,
3301− "license": "ISC"
3302− },
3303− "node_modules/npm/node_modules/npm-package-arg": {
3304− "version": "9.0.2",
3305− "inBundle": true,
3306− "license": "ISC",
2945+ "node_modules/vite-plugin-rewrite-all": {
2946+ "version": "0.1.2",
2947+ "resolved": "https://registry.npmjs.org/vite-plugin-rewrite-all/-/vite-plugin-rewrite-all-0.1.2.tgz",
2948+ "integrity": "sha512-hBFuG043kbixgZ/ke9SzKhkO6P8a5ryxD0CmZTe+/Cz17RIKi7uSeNUJy79V4FgavZ7pWVRg0tqVwJ7lP/A2/Q==",
2949+ "dev": true,
33072950 "dependencies": {
3308− "hosted-git-info": "^5.0.0",
3309− "semver": "^7.3.5",
3310− "validate-npm-package-name": "^4.0.0"
2951+ "connect-history-api-fallback": "^1.6.0"
33112952 },
33122953 "engines": {
3313− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2954+ "node": ">=12.0.0"
2955+ },
2956+ "peerDependencies": {
2957+ "vite": "^2.0.2"
33142958 }
33152959 },
3316− "node_modules/npm/node_modules/npm-packlist": {
3317− "version": "4.0.0",
3318− "inBundle": true,
3319− "license": "ISC",
2960+ "node_modules/which": {
2961+ "version": "2.0.2",
2962+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2963+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2964+ "dev": true,
33202965 "dependencies": {
3321− "glob": "^7.2.0",
3322− "ignore-walk": "^4.0.1",
3323− "npm-bundled": "^1.1.2",
3324− "npm-normalize-package-bin": "^1.0.1"
2966+ "isexe": "^2.0.0"
33252967 },
33262968 "bin": {
3327− "npm-packlist": "bin/index.js"
2969+ "node-which": "bin/node-which"
33282970 },
33292971 "engines": {
3330− "node": "^12.13.0 || ^14.15.0 || >=16"
2972+ "node": ">= 8"
33312973 }
33322974 },
3333− "node_modules/npm/node_modules/npm-pick-manifest": {
2975+ "node_modules/wrap-ansi": {
33342976 "version": "7.0.0",
3335− "inBundle": true,
3336− "license": "ISC",
3337− "dependencies": {
3338− "npm-install-checks": "^4.0.0",
3339− "npm-normalize-package-bin": "^1.0.1",
3340− "npm-package-arg": "^9.0.0",
3341− "semver": "^7.3.5"
3342− },
3343− "engines": {
3344− "node": "^12.13.0 || ^14.15.0 || >=16"
3345− }
3346− },
3347− "node_modules/npm/node_modules/npm-profile": {
3348− "version": "6.0.2",
3349− "inBundle": true,
3350− "license": "ISC",
2977+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2978+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2979+ "dev": true,
33512980 "dependencies": {
3352− "npm-registry-fetch": "^13.0.0",
3353− "proc-log": "^2.0.0"
2981+ "ansi-styles": "^4.0.0",
2982+ "string-width": "^4.1.0",
2983+ "strip-ansi": "^6.0.0"
33542984 },
33552985 "engines": {
3356− "node": "^12.13.0 || ^14.15.0 || >=16"
3357− }
3358− },
3359− "node_modules/npm/node_modules/npm-registry-fetch": {
3360− "version": "13.1.0",
3361− "inBundle": true,
3362− "license": "ISC",
3363− "dependencies": {
3364− "make-fetch-happen": "^10.0.6",
3365− "minipass": "^3.1.6",
3366− "minipass-fetch": "^2.0.3",
3367− "minipass-json-stream": "^1.0.1",
3368− "minizlib": "^2.1.2",
3369− "npm-package-arg": "^9.0.1",
3370− "proc-log": "^2.0.0"
2986+ "node": ">=10"
33712987 },
3372− "engines": {
3373− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
2988+ "funding": {
2989+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
33742990 }
33752991 },
3376− "node_modules/npm/node_modules/npm-user-validate": {
3377− "version": "1.0.1",
3378− "inBundle": true,
3379− "license": "BSD-2-Clause"
2992+ "node_modules/wrappy": {
2993+ "version": "1.0.2",
2994+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2995+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
2996+ "dev": true
33802997 },
3381− "node_modules/npm/node_modules/npmlog": {
3382− "version": "6.0.1",
3383− "inBundle": true,
3384− "license": "ISC",
2998+ "node_modules/xml-lexer": {
2999+ "version": "0.2.2",
3000+ "resolved": "https://registry.npmjs.org/xml-lexer/-/xml-lexer-0.2.2.tgz",
3001+ "integrity": "sha512-G0i98epIwiUEiKmMcavmVdhtymW+pCAohMRgybyIME9ygfVu8QheIi+YoQh3ngiThsT0SQzJT4R0sKDEv8Ou0w==",
33853002 "dependencies": {
3386− "are-we-there-yet": "^3.0.0",
3387− "console-control-strings": "^1.1.0",
3388− "gauge": "^4.0.0",
3389− "set-blocking": "^2.0.0"
3390− },
3391− "engines": {
3392− "node": "^12.13.0 || ^14.15.0 || >=16"
3003+ "eventemitter3": "^2.0.0"
33933004 }
33943005 },
3395− "node_modules/npm/node_modules/once": {
3396− "version": "1.4.0",
3397− "inBundle": true,
3398− "license": "ISC",
3006+ "node_modules/xml-reader": {
3007+ "version": "2.4.3",
3008+ "resolved": "https://registry.npmjs.org/xml-reader/-/xml-reader-2.4.3.tgz",
3009+ "integrity": "sha512-xWldrIxjeAMAu6+HSf9t50ot1uL5M+BtOidRCWHXIeewvSeIpscWCsp4Zxjk8kHHhdqFBrfK8U0EJeCcnyQ/gA==",
33993010 "dependencies": {
3400− "wrappy": "1"
3011+ "eventemitter3": "^2.0.0",
3012+ "xml-lexer": "^0.2.2"
34013013 }
34023014 },
3403− "node_modules/npm/node_modules/opener": {
3404− "version": "1.5.2",
3405− "inBundle": true,
3406− "license": "(WTFPL OR MIT)",
3407− "bin": {
3408− "opener": "bin/opener-bin.js"
3015+ "node_modules/xtend": {
3016+ "version": "4.0.2",
3017+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
3018+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
3019+ "dev": true,
3020+ "engines": {
3021+ "node": ">=0.4"
34093022 }
34103023 },
3411− "node_modules/npm/node_modules/p-map": {
3412− "version": "4.0.0",
3413− "inBundle": true,
3414− "license": "MIT",
3415− "dependencies": {
3416− "aggregate-error": "^3.0.0"
3417− },
3024+ "node_modules/y18n": {
3025+ "version": "5.0.8",
3026+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
3027+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
3028+ "dev": true,
34183029 "engines": {
34193030 "node": ">=10"
3420− },
3421− "funding": {
3422− "url": "https://github.com/sponsors/sindresorhus"
34233031 }
34243032 },
3425− "node_modules/npm/node_modules/pacote": {
3426− "version": "13.0.5",
3427− "inBundle": true,
3428− "license": "ISC",
3429− "dependencies": {
3430− "@npmcli/git": "^3.0.0",
3431− "@npmcli/installed-package-contents": "^1.0.7",
3432− "@npmcli/promise-spawn": "^1.2.0",
3433− "@npmcli/run-script": "^3.0.1",
3434− "cacache": "^16.0.0",
3435− "chownr": "^2.0.0",
3436− "fs-minipass": "^2.1.0",
3437− "infer-owner": "^1.0.4",
3438− "minipass": "^3.1.6",
3439− "mkdirp": "^1.0.4",
3440− "npm-package-arg": "^9.0.0",
3441− "npm-packlist": "^4.0.0",
3442− "npm-pick-manifest": "^7.0.0",
3443− "npm-registry-fetch": "^13.0.1",
3444− "proc-log": "^2.0.0",
3445− "promise-retry": "^2.0.1",
3446− "read-package-json": "^5.0.0",
3447− "read-package-json-fast": "^2.0.3",
3448− "rimraf": "^3.0.2",
3449− "ssri": "^8.0.1",
3450− "tar": "^6.1.11"
3451− },
3452− "bin": {
3453− "pacote": "lib/bin.js"
3454− },
3033+ "node_modules/yaml": {
3034+ "version": "1.10.2",
3035+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
3036+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
3037+ "dev": true,
34553038 "engines": {
3456− "node": "^12.13.0 || ^14.15.0 || >=16"
3039+ "node": ">= 6"
34573040 }
34583041 },
3459− "node_modules/npm/node_modules/parse-conflict-json": {
3460− "version": "2.0.2",
3461− "inBundle": true,
3462− "license": "ISC",
3042+ "node_modules/yargs": {
3043+ "version": "16.2.0",
3044+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
3045+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
3046+ "dev": true,
34633047 "dependencies": {
3464− "json-parse-even-better-errors": "^2.3.1",
3465− "just-diff": "^5.0.1",
3466− "just-diff-apply": "^5.2.0"
3048+ "cliui": "^7.0.2",
3049+ "escalade": "^3.1.1",
3050+ "get-caller-file": "^2.0.5",
3051+ "require-directory": "^2.1.1",
3052+ "string-width": "^4.2.0",
3053+ "y18n": "^5.0.5",
3054+ "yargs-parser": "^20.2.2"
34673055 },
34683056 "engines": {
3469− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
3470− }
3471− },
3472− "node_modules/npm/node_modules/path-is-absolute": {
3473− "version": "1.0.1",
3474− "inBundle": true,
3475− "license": "MIT",
3476− "engines": {
3477− "node": ">=0.10.0"
3057+ "node": ">=10"
34783058 }
34793059 },
3480− "node_modules/npm/node_modules/proc-log": {
3481− "version": "2.0.1",
3482− "inBundle": true,
3483− "license": "ISC",
3060+ "node_modules/yargs-parser": {
3061+ "version": "20.2.9",
3062+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
3063+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
3064+ "dev": true,
34843065 "engines": {
3485− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
3486− }
3487− },
3488− "node_modules/npm/node_modules/promise-all-reject-late": {
3489− "version": "1.0.1",
3490− "inBundle": true,
3491− "license": "ISC",
3492− "funding": {
3493− "url": "https://github.com/sponsors/isaacs"
3066+ "node": ">=10"
34943067 }
3495− },
3496− "node_modules/npm/node_modules/promise-call-limit": {
3497− "version": "1.0.1",
3498− "inBundle": true,
3499− "license": "ISC",
3500− "funding": {
3501− "url": "https://github.com/sponsors/isaacs"
3068+ }
3069+ },
3070+ "dependencies": {
3071+ "@babel/code-frame": {
3072+ "version": "7.16.7",
3073+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
3074+ "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
3075+ "dev": true,
3076+ "requires": {
3077+ "@babel/highlight": "^7.16.7"
35023078 }
35033079 },
3504− "node_modules/npm/node_modules/promise-inflight": {
3505− "version": "1.0.1",
3506− "inBundle": true,
3507− "license": "ISC"
3080+ "@babel/helper-validator-identifier": {
3081+ "version": "7.16.7",
3082+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
3083+ "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==",
3084+ "dev": true
35083085 },
3509− "node_modules/npm/node_modules/promise-retry": {
3510− "version": "2.0.1",
3511− "inBundle": true,
3512− "license": "MIT",
3513− "dependencies": {
3514− "err-code": "^2.0.2",
3515− "retry": "^0.12.0"
3086+ "@babel/highlight": {
3087+ "version": "7.16.7",
3088+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz",
3089+ "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==",
3090+ "dev": true,
3091+ "requires": {
3092+ "@babel/helper-validator-identifier": "^7.16.7",
3093+ "chalk": "^2.0.0",
3094+ "js-tokens": "^4.0.0"
35163095 },
3517− "engines": {
3518− "node": ">=10"
3519− }
3520− },
3521− "node_modules/npm/node_modules/promzard": {
3522− "version": "0.3.0",
3523− "inBundle": true,
3524− "license": "ISC",
35253096 "dependencies": {
3526− "read": "1"
3097+ "ansi-styles": {
3098+ "version": "3.2.1",
3099+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
3100+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
3101+ "dev": true,
3102+ "requires": {
3103+ "color-convert": "^1.9.0"
3104+ }
3105+ },
3106+ "chalk": {
3107+ "version": "2.4.2",
3108+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
3109+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
3110+ "dev": true,
3111+ "requires": {
3112+ "ansi-styles": "^3.2.1",
3113+ "escape-string-regexp": "^1.0.5",
3114+ "supports-color": "^5.3.0"
3115+ }
3116+ },
3117+ "color-convert": {
3118+ "version": "1.9.3",
3119+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
3120+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
3121+ "dev": true,
3122+ "requires": {
3123+ "color-name": "1.1.3"
3124+ }
3125+ },
3126+ "color-name": {
3127+ "version": "1.1.3",
3128+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
3129+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
3130+ "dev": true
3131+ },
3132+ "has-flag": {
3133+ "version": "3.0.0",
3134+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
3135+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
3136+ "dev": true
3137+ },
3138+ "supports-color": {
3139+ "version": "5.5.0",
3140+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
3141+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
3142+ "dev": true,
3143+ "requires": {
3144+ "has-flag": "^3.0.0"
3145+ }
3146+ }
35273147 }
35283148 },
3529− "node_modules/npm/node_modules/qrcode-terminal": {
3530− "version": "0.12.0",
3531− "inBundle": true,
3532− "bin": {
3533− "qrcode-terminal": "bin/qrcode-terminal.js"
3149+ "@babel/runtime": {
3150+ "version": "7.16.7",
3151+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz",
3152+ "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==",
3153+ "requires": {
3154+ "regenerator-runtime": "^0.13.4"
35343155 }
35353156 },
3536− "node_modules/npm/node_modules/read": {
3537− "version": "1.0.7",
3538− "inBundle": true,
3539− "license": "ISC",
3540− "dependencies": {
3541− "mute-stream": "~0.0.4"
3542− },
3543− "engines": {
3544− "node": ">=0.8"
3157+ "@johnhyde/sigil-js": {
3158+ "version": "git+ssh://git@github.com/johnhyde/sigil-js.git#f89ce78c34b5811ea19ddea4a6964ea8360e7b4d",
3159+ "from": "@johnhyde/sigil-js@github:johnhyde/sigil-js",
3160+ "requires": {
3161+ "invariant": "^2.2.4",
3162+ "svgson": "^4.0.0",
3163+ "transformation-matrix": "2.1.1"
35453164 }
35463165 },
3547− "node_modules/npm/node_modules/read-cmd-shim": {
3548− "version": "2.0.0",
3549− "inBundle": true,
3550− "license": "ISC"
3551− },
3552− "node_modules/npm/node_modules/read-package-json": {
3553− "version": "5.0.0",
3554− "inBundle": true,
3555− "license": "ISC",
3556− "dependencies": {
3557− "glob": "^7.2.0",
3558− "json-parse-even-better-errors": "^2.3.1",
3559− "normalize-package-data": "^4.0.0",
3560− "npm-normalize-package-bin": "^1.0.1"
3561− },
3562− "engines": {
3563− "node": "^12.13.0 || ^14.15.0 || >=16"
3564− }
3166+ "@microsoft/fetch-event-source": {
3167+ "version": "2.0.1",
3168+ "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz",
3169+ "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA=="
35653170 },
3566− "node_modules/npm/node_modules/read-package-json-fast": {
3567− "version": "2.0.3",
3568− "inBundle": true,
3569− "license": "ISC",
3570− "dependencies": {
3571− "json-parse-even-better-errors": "^2.3.0",
3572− "npm-normalize-package-bin": "^1.0.1"
3573− },
3574− "engines": {
3575− "node": ">=10"
3171+ "@nodelib/fs.scandir": {
3172+ "version": "2.1.5",
3173+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
3174+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
3175+ "dev": true,
3176+ "requires": {
3177+ "@nodelib/fs.stat": "2.0.5",
3178+ "run-parallel": "^1.1.9"
35763179 }
35773180 },
3578− "node_modules/npm/node_modules/readable-stream": {
3579− "version": "3.6.0",
3580− "inBundle": true,
3581− "license": "MIT",
3582− "dependencies": {
3583− "inherits": "^2.0.3",
3584− "string_decoder": "^1.1.1",
3585− "util-deprecate": "^1.0.1"
3586− },
3587− "engines": {
3588− "node": ">= 6"
3589− }
3181+ "@nodelib/fs.stat": {
3182+ "version": "2.0.5",
3183+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
3184+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
3185+ "dev": true
35903186 },
3591− "node_modules/npm/node_modules/readdir-scoped-modules": {
3592− "version": "1.1.0",
3593− "inBundle": true,
3594− "license": "ISC",
3595− "dependencies": {
3596− "debuglog": "^1.0.1",
3597− "dezalgo": "^1.0.0",
3598− "graceful-fs": "^4.1.2",
3599− "once": "^1.3.0"
3187+ "@nodelib/fs.walk": {
3188+ "version": "1.2.8",
3189+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
3190+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
3191+ "dev": true,
3192+ "requires": {
3193+ "@nodelib/fs.scandir": "2.1.5",
3194+ "fastq": "^1.6.0"
36003195 }
36013196 },
3602− "node_modules/npm/node_modules/retry": {
3603− "version": "0.12.0",
3604− "inBundle": true,
3605− "license": "MIT",
3606− "engines": {
3607− "node": ">= 4"
3608− }
3197+ "@popperjs/core": {
3198+ "version": "2.11.5",
3199+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz",
3200+ "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw=="
36093201 },
3610− "node_modules/npm/node_modules/rimraf": {
3611− "version": "3.0.2",
3612− "inBundle": true,
3613− "license": "ISC",
3614− "dependencies": {
3615− "glob": "^7.1.3"
3616− },
3617− "bin": {
3618− "rimraf": "bin.js"
3619− },
3620− "funding": {
3621− "url": "https://github.com/sponsors/isaacs"
3202+ "@rollup/pluginutils": {
3203+ "version": "4.1.2",
3204+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.1.2.tgz",
3205+ "integrity": "sha512-ROn4qvkxP9SyPeHaf7uQC/GPFY6L/OWy9+bd9AwcjOAWQwxRscoEyAUD8qCY5o5iL4jqQwoLk2kaTKJPb/HwzQ==",
3206+ "dev": true,
3207+ "requires": {
3208+ "estree-walker": "^2.0.1",
3209+ "picomatch": "^2.2.2"
36223210 }
36233211 },
3624− "node_modules/npm/node_modules/safe-buffer": {
3625− "version": "5.2.1",
3626− "funding": [
3627− {
3628− "type": "github",
3629− "url": "https://github.com/sponsors/feross"
3630− },
3631− {
3632− "type": "patreon",
3633− "url": "https://www.patreon.com/feross"
3634− },
3635− {
3636− "type": "consulting",
3637− "url": "https://feross.org/support"
3638− }
3639− ],
3640− "inBundle": true,
3641− "license": "MIT"
3642− },
3643− "node_modules/npm/node_modules/safer-buffer": {
3644− "version": "2.1.2",
3645− "inBundle": true,
3646− "license": "MIT",
3647− "optional": true
3648− },
3649− "node_modules/npm/node_modules/semver": {
3650− "version": "7.3.5",
3651− "inBundle": true,
3652− "license": "ISC",
3653− "dependencies": {
3654− "lru-cache": "^6.0.0"
3655− },
3656− "bin": {
3657− "semver": "bin/semver.js"
3658− },
3659− "engines": {
3660− "node": ">=10"
3212+ "@sveltejs/vite-plugin-svelte": {
3213+ "version": "1.0.0-next.34",
3214+ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.34.tgz",
3215+ "integrity": "sha512-qZH2jndijrdkvevgbO7OH3iQsviM5Kz7h5APiNP4yEMZTrwq9bifzYvco6BprwtPvLb5wYlRVFZUOdusY6AovQ==",
3216+ "dev": true,
3217+ "requires": {
3218+ "@rollup/pluginutils": "^4.1.2",
3219+ "debug": "^4.3.3",
3220+ "kleur": "^4.1.4",
3221+ "magic-string": "^0.25.7",
3222+ "require-relative": "^0.8.7",
3223+ "svelte-hmr": "^0.14.9"
36613224 }
36623225 },
3663− "node_modules/npm/node_modules/semver/node_modules/lru-cache": {
3664− "version": "6.0.0",
3665− "inBundle": true,
3666− "license": "ISC",
3667− "dependencies": {
3668− "yallist": "^4.0.0"
3669− },
3670− "engines": {
3671− "node": ">=10"
3226+ "@tlon/phonemes-js": {
3227+ "version": "1.0.0",
3228+ "resolved": "https://registry.npmjs.org/@tlon/phonemes-js/-/phonemes-js-1.0.0.tgz",
3229+ "integrity": "sha512-o8zLHidOYkn5So6BSKduueoJBKBK97Q9Puwo/9Orae1DDhEGE8HqYvbGNaT6VuIMiuK8WoB/FAx5hHUrnQ5GxQ=="
3230+ },
3231+ "@tlon/sigil-js": {
3232+ "version": "1.4.5",
3233+ "resolved": "https://registry.npmjs.org/@tlon/sigil-js/-/sigil-js-1.4.5.tgz",
3234+ "integrity": "sha512-+Fn0EizPetjePaK+z8njjzE74wxzqIRLVM8W53Dlri6XU87wJ4vk82baVGgZQFAQs96rYM/f4WV7kCzuSxSMAw==",
3235+ "requires": {
3236+ "invariant": "^2.2.4",
3237+ "svgson": "^4.0.0",
3238+ "transformation-matrix": "2.1.1"
36723239 }
36733240 },
3674− "node_modules/npm/node_modules/set-blocking": {
3675− "version": "2.0.0",
3676− "inBundle": true,
3677− "license": "ISC"
3241+ "@tsconfig/svelte": {
3242+ "version": "2.0.1",
3243+ "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-2.0.1.tgz",
3244+ "integrity": "sha512-aqkICXbM1oX5FfgZd2qSSAGdyo/NRxjWCamxoyi3T8iVQnzGge19HhDYzZ6NrVOW7bhcWNSq9XexWFtMzbB24A==",
3245+ "dev": true
36783246 },
3679− "node_modules/npm/node_modules/signal-exit": {
3680− "version": "3.0.7",
3681− "inBundle": true,
3682− "license": "ISC"
3247+ "@types/marked": {
3248+ "version": "4.0.7",
3249+ "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.7.tgz",
3250+ "integrity": "sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw=="
36833251 },
3684− "node_modules/npm/node_modules/smart-buffer": {
3685− "version": "4.2.0",
3686− "inBundle": true,
3687− "license": "MIT",
3688− "engines": {
3689− "node": ">= 6.0.0",
3690− "npm": ">= 3.0.0"
3691− }
3252+ "@types/node": {
3253+ "version": "17.0.8",
3254+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.8.tgz",
3255+ "integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==",
3256+ "dev": true
36923257 },
3693− "node_modules/npm/node_modules/socks": {
3694− "version": "2.6.2",
3695− "inBundle": true,
3696− "license": "MIT",
3697− "dependencies": {
3698− "ip": "^1.1.5",
3699− "smart-buffer": "^4.2.0"
3700− },
3701− "engines": {
3702− "node": ">= 10.13.0",
3703− "npm": ">= 3.0.0"
3704− }
3258+ "@types/parse-json": {
3259+ "version": "4.0.0",
3260+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
3261+ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
3262+ "dev": true
37053263 },
3706− "node_modules/npm/node_modules/socks-proxy-agent": {
3707− "version": "6.1.1",
3708− "inBundle": true,
3709− "license": "MIT",
3710− "dependencies": {
3711− "agent-base": "^6.0.2",
3712− "debug": "^4.3.1",
3713− "socks": "^2.6.1"
3714− },
3715− "engines": {
3716− "node": ">= 10"
3717− }
3264+ "@types/pug": {
3265+ "version": "2.0.6",
3266+ "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz",
3267+ "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==",
3268+ "dev": true
37183269 },
3719− "node_modules/npm/node_modules/spdx-correct": {
3720− "version": "3.1.1",
3721− "inBundle": true,
3722− "license": "Apache-2.0",
3723− "dependencies": {
3724− "spdx-expression-parse": "^3.0.0",
3725− "spdx-license-ids": "^3.0.0"
3270+ "@types/sass": {
3271+ "version": "1.43.1",
3272+ "resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.43.1.tgz",
3273+ "integrity": "sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==",
3274+ "dev": true,
3275+ "requires": {
3276+ "@types/node": "*"
37263277 }
37273278 },
3728− "node_modules/npm/node_modules/spdx-exceptions": {
3729− "version": "2.3.0",
3730− "inBundle": true,
3731− "license": "CC-BY-3.0"
3732− },
3733− "node_modules/npm/node_modules/spdx-expression-parse": {
3734− "version": "3.0.1",
3735− "inBundle": true,
3736− "license": "MIT",
3737− "dependencies": {
3738− "spdx-exceptions": "^2.1.0",
3739− "spdx-license-ids": "^3.0.0"
3279+ "@urbit/api": {
3280+ "version": "2.1.0",
3281+ "resolved": "https://registry.npmjs.org/@urbit/api/-/api-2.1.0.tgz",
3282+ "integrity": "sha512-2njwpvZ2s23gp5C4v9uDynU1wxrN33+vloqpvlErUhMR/4R6mXE4cMvsZzj/fCGOa0J3LRV/If7XmgG+kY69Tg==",
3283+ "requires": {
3284+ "@babel/runtime": "^7.16.0",
3285+ "big-integer": "^1.6.48",
3286+ "core-js": "^3.19.1",
3287+ "immer": "^9.0.1",
3288+ "urbit-ob": "^5.0.1"
37403289 }
37413290 },
3742− "node_modules/npm/node_modules/spdx-license-ids": {
3743− "version": "3.0.11",
3744− "inBundle": true,
3745− "license": "CC0-1.0"
3746− },
3747− "node_modules/npm/node_modules/ssri": {
3748− "version": "8.0.1",
3749− "inBundle": true,
3750− "license": "ISC",
3751− "dependencies": {
3752− "minipass": "^3.1.1"
3753− },
3754− "engines": {
3755− "node": ">= 8"
3291+ "@urbit/http-api": {
3292+ "version": "2.1.0",
3293+ "resolved": "https://registry.npmjs.org/@urbit/http-api/-/http-api-2.1.0.tgz",
3294+ "integrity": "sha512-eXYar3ofw1HlhHy2NSkJPCo//oZzfnrGXIJAKQ/gWSzd8x3o7eiiIQjoFbuWojaACy8T9fXsGzpxEqoXZlWDhw==",
3295+ "requires": {
3296+ "@babel/runtime": "^7.12.5",
3297+ "@microsoft/fetch-event-source": "^2.0.0",
3298+ "browser-or-node": "^1.3.0",
3299+ "core-js": "^3.19.1"
37563300 }
37573301 },
3758− "node_modules/npm/node_modules/string_decoder": {
3759− "version": "1.3.0",
3760− "inBundle": true,
3761− "license": "MIT",
3762− "dependencies": {
3763− "safe-buffer": "~5.2.0"
3302+ "@urbit/vite-plugin-urbit": {
3303+ "version": "0.8.0",
3304+ "resolved": "https://registry.npmjs.org/@urbit/vite-plugin-urbit/-/vite-plugin-urbit-0.8.0.tgz",
3305+ "integrity": "sha512-cx540xZBuHfzud/kOuYU4xPpsFcgE7mF0heac5uXVutDqjySvVXimEuZgBN23ULC7l60R/bAJ2jOWygBwWen4A==",
3306+ "dev": true,
3307+ "requires": {
3308+ "vite-plugin-html-config": "^1.0.6",
3309+ "vite-plugin-rewrite-all": "^0.1.2"
37643310 }
37653311 },
3766− "node_modules/npm/node_modules/string-width": {
3767− "version": "4.2.3",
3768− "inBundle": true,
3769− "license": "MIT",
3770− "dependencies": {
3771− "emoji-regex": "^8.0.0",
3772− "is-fullwidth-code-point": "^3.0.0",
3773− "strip-ansi": "^6.0.1"
3774− },
3775− "engines": {
3776− "node": ">=8"
3777− }
3312+ "@yomguithereal/helpers": {
3313+ "version": "1.1.1",
3314+ "resolved": "https://registry.npmjs.org/@yomguithereal/helpers/-/helpers-1.1.1.tgz",
3315+ "integrity": "sha512-UYvAq/XCA7xoh1juWDYsq3W0WywOB+pz8cgVnE1b45ZfdMhBvHDrgmSFG3jXeZSr2tMTYLGHFHON+ekG05Jebg=="
37783316 },
3779− "node_modules/npm/node_modules/stringify-package": {
3780− "version": "1.0.1",
3781− "inBundle": true,
3782− "license": "ISC"
3317+ "acorn": {
3318+ "version": "7.4.1",
3319+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
3320+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
3321+ "dev": true
37833322 },
3784− "node_modules/npm/node_modules/strip-ansi": {
3785− "version": "6.0.1",
3786− "inBundle": true,
3787− "license": "MIT",
3788− "dependencies": {
3789− "ansi-regex": "^5.0.1"
3790− },
3791− "engines": {
3792− "node": ">=8"
3323+ "acorn-node": {
3324+ "version": "1.8.2",
3325+ "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
3326+ "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
3327+ "dev": true,
3328+ "requires": {
3329+ "acorn": "^7.0.0",
3330+ "acorn-walk": "^7.0.0",
3331+ "xtend": "^4.0.2"
37933332 }
37943333 },
3795− "node_modules/npm/node_modules/supports-color": {
3334+ "acorn-walk": {
37963335 "version": "7.2.0",
3797− "inBundle": true,
3798− "license": "MIT",
3799− "dependencies": {
3800− "has-flag": "^4.0.0"
3801− },
3802− "engines": {
3803− "node": ">=8"
3804− }
3805− },
3806− "node_modules/npm/node_modules/tar": {
3807− "version": "6.1.11",
3808− "inBundle": true,
3809− "license": "ISC",
3810− "dependencies": {
3811− "chownr": "^2.0.0",
3812− "fs-minipass": "^2.0.0",
3813− "minipass": "^3.0.0",
3814− "minizlib": "^2.1.1",
3815− "mkdirp": "^1.0.3",
3816− "yallist": "^4.0.0"
3817− },
3818− "engines": {
3819− "node": ">= 10"
3820− }
3821− },
3822− "node_modules/npm/node_modules/text-table": {
3823− "version": "0.2.0",
3824− "inBundle": true,
3825− "license": "MIT"
3826− },
3827− "node_modules/npm/node_modules/tiny-relative-date": {
3828− "version": "1.3.0",
3829− "inBundle": true,
3830− "license": "MIT"
3336+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
3337+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
3338+ "dev": true
38313339 },
3832− "node_modules/npm/node_modules/treeverse": {
3833− "version": "1.0.4",
3834− "inBundle": true,
3835− "license": "ISC"
3340+ "ansi-regex": {
3341+ "version": "5.0.1",
3342+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
3343+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
3344+ "dev": true
38363345 },
3837− "node_modules/npm/node_modules/unique-filename": {
3838− "version": "1.1.1",
3839− "inBundle": true,
3840− "license": "ISC",
3841− "dependencies": {
3842− "unique-slug": "^2.0.0"
3346+ "ansi-styles": {
3347+ "version": "4.3.0",
3348+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
3349+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
3350+ "dev": true,
3351+ "requires": {
3352+ "color-convert": "^2.0.1"
38433353 }
38443354 },
3845− "node_modules/npm/node_modules/unique-slug": {
3846− "version": "2.0.2",
3847− "inBundle": true,
3848− "license": "ISC",
3849− "dependencies": {
3850− "imurmurhash": "^0.1.4"
3355+ "anymatch": {
3356+ "version": "3.1.2",
3357+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
3358+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
3359+ "dev": true,
3360+ "requires": {
3361+ "normalize-path": "^3.0.0",
3362+ "picomatch": "^2.0.4"
38513363 }
38523364 },
3853− "node_modules/npm/node_modules/util-deprecate": {
3854− "version": "1.0.2",
3855− "inBundle": true,
3856− "license": "MIT"
3857− },
3858− "node_modules/npm/node_modules/validate-npm-package-license": {
3859− "version": "3.0.4",
3860− "inBundle": true,
3861− "license": "Apache-2.0",
3862− "dependencies": {
3863− "spdx-correct": "^3.0.0",
3864− "spdx-expression-parse": "^3.0.0"
3865− }
3365+ "arg": {
3366+ "version": "5.0.1",
3367+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.1.tgz",
3368+ "integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==",
3369+ "dev": true
38663370 },
3867− "node_modules/npm/node_modules/validate-npm-package-name": {
3868− "version": "4.0.0",
3869− "inBundle": true,
3870− "license": "ISC",
3871− "dependencies": {
3872− "builtins": "^5.0.0"
3873− },
3874− "engines": {
3875− "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
3876− }
3371+ "array-union": {
3372+ "version": "3.0.1",
3373+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz",
3374+ "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==",
3375+ "dev": true
38773376 },
3878− "node_modules/npm/node_modules/walk-up-path": {
3879− "version": "1.0.0",
3880− "inBundle": true,
3881− "license": "ISC"
3882− },
3883− "node_modules/npm/node_modules/wcwidth": {
3884− "version": "1.0.1",
3885− "inBundle": true,
3886− "license": "MIT",
3887− "dependencies": {
3888− "defaults": "^1.0.3"
3889− }
3890− },
3891− "node_modules/npm/node_modules/which": {
3892− "version": "2.0.2",
3893− "inBundle": true,
3894− "license": "ISC",
3895− "dependencies": {
3896− "isexe": "^2.0.0"
3897− },
3898− "bin": {
3899− "node-which": "bin/node-which"
3900− },
3901− "engines": {
3902− "node": ">= 8"
3903− }
3904− },
3905− "node_modules/npm/node_modules/wide-align": {
3906− "version": "1.1.5",
3907− "inBundle": true,
3908− "license": "ISC",
3909− "dependencies": {
3910− "string-width": "^1.0.2 || 2 || 3 || 4"
3377+ "autoprefixer": {
3378+ "version": "10.4.2",
3379+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz",
3380+ "integrity": "sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==",
3381+ "dev": true,
3382+ "requires": {
3383+ "browserslist": "^4.19.1",
3384+ "caniuse-lite": "^1.0.30001297",
3385+ "fraction.js": "^4.1.2",
3386+ "normalize-range": "^0.1.2",
3387+ "picocolors": "^1.0.0",
3388+ "postcss-value-parser": "^4.2.0"
39113389 }
39123390 },
3913− "node_modules/npm/node_modules/wrappy": {
3391+ "balanced-match": {
39143392 "version": "1.0.2",
3915− "inBundle": true,
3916− "license": "ISC"
3393+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
3394+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
3395+ "dev": true
39173396 },
3918− "node_modules/npm/node_modules/write-file-atomic": {
3919− "version": "4.0.1",
3920− "inBundle": true,
3921− "license": "ISC",
3922− "dependencies": {
3923− "imurmurhash": "^0.1.4",
3924− "signal-exit": "^3.0.7"
3925− },
3926− "engines": {
3927− "node": "^12.13.0 || ^14.15.0 || >=16"
3928− }
3397+ "big-integer": {
3398+ "version": "1.6.51",
3399+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
3400+ "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg=="
39293401 },
3930− "node_modules/npm/node_modules/yallist": {
3931− "version": "4.0.0",
3932− "inBundle": true,
3933− "license": "ISC"
3402+ "binary-extensions": {
3403+ "version": "2.2.0",
3404+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
3405+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
3406+ "dev": true
39343407 },
3935− "node_modules/object-assign": {
3936− "version": "4.1.1",
3937− "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
3938− "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
3939− "peer": true,
3940− "engines": {
3941− "node": ">=0.10.0"
3942− }
3408+ "bn.js": {
3409+ "version": "5.2.0",
3410+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
3411+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
39433412 },
3944− "node_modules/object-hash": {
3945− "version": "2.2.0",
3946− "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
3947− "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
3413+ "brace-expansion": {
3414+ "version": "1.1.11",
3415+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
3416+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
39483417 "dev": true,
3949− "engines": {
3950− "node": ">= 6"
3418+ "requires": {
3419+ "balanced-match": "^1.0.0",
3420+ "concat-map": "0.0.1"
39513421 }
39523422 },
3953− "node_modules/omit-deep": {
3954− "version": "0.3.0",
3955− "resolved": "https://registry.npmjs.org/omit-deep/-/omit-deep-0.3.0.tgz",
3956− "integrity": "sha1-IcivNJm8rdKWUaIyy8rLxSRF6+w=",
3957− "dependencies": {
3958− "is-plain-object": "^2.0.1",
3959− "unset-value": "^0.1.1"
3960− },
3961− "engines": {
3962− "node": ">=0.10.0"
3423+ "braces": {
3424+ "version": "3.0.2",
3425+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
3426+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
3427+ "dev": true,
3428+ "requires": {
3429+ "fill-range": "^7.0.1"
39633430 }
39643431 },
3965− "node_modules/once": {
3966− "version": "1.4.0",
3967− "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
3968− "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
3432+ "browser-or-node": {
3433+ "version": "1.3.0",
3434+ "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-1.3.0.tgz",
3435+ "integrity": "sha512-0F2z/VSnLbmEeBcUrSuDH5l0HxTXdQQzLjkmBR4cYfvg1zJrKSlmIZFqyFR8oX0NrwPhy3c3HQ6i3OxMbew4Tg=="
3436+ },
3437+ "browserslist": {
3438+ "version": "4.19.1",
3439+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz",
3440+ "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==",
39693441 "dev": true,
3970− "dependencies": {
3971− "wrappy": "1"
3442+ "requires": {
3443+ "caniuse-lite": "^1.0.30001286",
3444+ "electron-to-chromium": "^1.4.17",
3445+ "escalade": "^3.1.1",
3446+ "node-releases": "^2.0.1",
3447+ "picocolors": "^1.0.0"
39723448 }
39733449 },
3974− "node_modules/parent-module": {
3975− "version": "1.0.1",
3976− "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
3977− "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
3450+ "buffer-crc32": {
3451+ "version": "0.2.13",
3452+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
3453+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
3454+ "dev": true
3455+ },
3456+ "callsites": {
3457+ "version": "3.1.0",
3458+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
3459+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
3460+ "dev": true
3461+ },
3462+ "camelcase-css": {
3463+ "version": "2.0.1",
3464+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
3465+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
3466+ "dev": true
3467+ },
3468+ "caniuse-lite": {
3469+ "version": "1.0.30001297",
3470+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001297.tgz",
3471+ "integrity": "sha512-6bbIbowYG8vFs/Lk4hU9jFt7NknGDleVAciK916tp6ft1j+D//ZwwL6LbF1wXMQ32DMSjeuUV8suhh6dlmFjcA==",
3472+ "dev": true
3473+ },
3474+ "chalk": {
3475+ "version": "4.1.2",
3476+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
3477+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
39783478 "dev": true,
3979− "dependencies": {
3980− "callsites": "^3.0.0"
3981− },
3982− "engines": {
3983− "node": ">=6"
3479+ "requires": {
3480+ "ansi-styles": "^4.1.0",
3481+ "supports-color": "^7.1.0"
39843482 }
39853483 },
3986− "node_modules/parse-json": {
3987− "version": "5.2.0",
3988− "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
3989− "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
3484+ "chokidar": {
3485+ "version": "3.5.2",
3486+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
3487+ "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
39903488 "dev": true,
3991− "dependencies": {
3992− "@babel/code-frame": "^7.0.0",
3993− "error-ex": "^1.3.1",
3994− "json-parse-even-better-errors": "^2.3.0",
3995− "lines-and-columns": "^1.1.6"
3996− },
3997− "engines": {
3998− "node": ">=8"
3999− },
4000− "funding": {
4001− "url": "https://github.com/sponsors/sindresorhus"
3489+ "requires": {
3490+ "anymatch": "~3.1.2",
3491+ "braces": "~3.0.2",
3492+ "fsevents": "~2.3.2",
3493+ "glob-parent": "~5.1.2",
3494+ "is-binary-path": "~2.1.0",
3495+ "is-glob": "~4.0.1",
3496+ "normalize-path": "~3.0.0",
3497+ "readdirp": "~3.6.0"
40023498 }
40033499 },
4004− "node_modules/path-is-absolute": {
4005− "version": "1.0.1",
4006− "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
4007− "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
3500+ "cliui": {
3501+ "version": "7.0.4",
3502+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
3503+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
40083504 "dev": true,
4009− "engines": {
4010− "node": ">=0.10.0"
3505+ "requires": {
3506+ "string-width": "^4.2.0",
3507+ "strip-ansi": "^6.0.0",
3508+ "wrap-ansi": "^7.0.0"
40113509 }
40123510 },
4013− "node_modules/path-key": {
4014− "version": "3.1.1",
4015− "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
4016− "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
3511+ "color-convert": {
3512+ "version": "2.0.1",
3513+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
3514+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
40173515 "dev": true,
4018− "engines": {
4019− "node": ">=8"
3516+ "requires": {
3517+ "color-name": "~1.1.4"
40203518 }
40213519 },
4022− "node_modules/path-parse": {
4023− "version": "1.0.7",
4024− "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
4025− "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
3520+ "color-name": {
3521+ "version": "1.1.4",
3522+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
3523+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
40263524 "dev": true
40273525 },
4028− "node_modules/path-type": {
4029− "version": "4.0.0",
4030− "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
4031− "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
3526+ "concat-map": {
3527+ "version": "0.0.1",
3528+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
3529+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
3530+ "dev": true
3531+ },
3532+ "concurrently": {
3533+ "version": "7.0.0",
3534+ "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.0.0.tgz",
3535+ "integrity": "sha512-WKM7PUsI8wyXpF80H+zjHP32fsgsHNQfPLw/e70Z5dYkV7hF+rf8q3D+ScWJIEr57CpkO3OWBko6hwhQLPR8Pw==",
40323536 "dev": true,
4033− "engines": {
4034− "node": ">=8"
3537+ "requires": {
3538+ "chalk": "^4.1.0",
3539+ "date-fns": "^2.16.1",
3540+ "lodash": "^4.17.21",
3541+ "rxjs": "^6.6.3",
3542+ "spawn-command": "^0.0.2-1",
3543+ "supports-color": "^8.1.0",
3544+ "tree-kill": "^1.2.2",
3545+ "yargs": "^16.2.0"
3546+ },
3547+ "dependencies": {
3548+ "supports-color": {
3549+ "version": "8.1.1",
3550+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
3551+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
3552+ "dev": true,
3553+ "requires": {
3554+ "has-flag": "^4.0.0"
3555+ }
3556+ }
40353557 }
40363558 },
4037− "node_modules/picocolors": {
4038− "version": "1.0.0",
4039− "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
4040− "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
3559+ "connect-history-api-fallback": {
3560+ "version": "1.6.0",
3561+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
3562+ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
40413563 "dev": true
40423564 },
4043− "node_modules/picomatch": {
4044− "version": "2.3.1",
4045− "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
4046− "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
4047− "engines": {
4048− "node": ">=8.6"
4049− },
4050− "funding": {
4051− "url": "https://github.com/sponsors/jonschlinkert"
4052− }
3565+ "core-js": {
3566+ "version": "3.20.2",
3567+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.2.tgz",
3568+ "integrity": "sha512-nuqhq11DcOAbFBV4zCbKeGbKQsUDRqTX0oqx7AttUBuqe3h20ixsE039QHelbL6P4h+9kytVqyEtyZ6gsiwEYw=="
40533569 },
4054− "node_modules/pify": {
4055− "version": "2.3.0",
4056− "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
4057− "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
3570+ "cosmiconfig": {
3571+ "version": "7.0.1",
3572+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
3573+ "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
40583574 "dev": true,
4059− "engines": {
4060− "node": ">=0.10.0"
3575+ "requires": {
3576+ "@types/parse-json": "^4.0.0",
3577+ "import-fresh": "^3.2.1",
3578+ "parse-json": "^5.0.0",
3579+ "path-type": "^4.0.0",
3580+ "yaml": "^1.10.0"
40613581 }
40623582 },
4063− "node_modules/postcss": {
4064− "version": "8.4.5",
4065− "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
4066− "integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
3583+ "cross-env": {
3584+ "version": "7.0.3",
3585+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
3586+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
40673587 "dev": true,
4068− "dependencies": {
4069− "nanoid": "^3.1.30",
4070− "picocolors": "^1.0.0",
4071− "source-map-js": "^1.0.1"
4072− },
4073− "engines": {
4074− "node": "^10 || ^12 || >=14"
4075− },
4076− "funding": {
4077− "type": "opencollective",
4078− "url": "https://opencollective.com/postcss/"
3588+ "requires": {
3589+ "cross-spawn": "^7.0.1"
40793590 }
40803591 },
4081− "node_modules/postcss-cli": {
4082− "version": "9.1.0",
4083− "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-9.1.0.tgz",
4084− "integrity": "sha512-zvDN2ADbWfza42sAnj+O2uUWyL0eRL1V+6giM2vi4SqTR3gTYy8XzcpfwccayF2szcUif0HMmXiEaDv9iEhcpw==",
3592+ "cross-spawn": {
3593+ "version": "7.0.3",
3594+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
3595+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
40853596 "dev": true,
4086− "dependencies": {
4087− "chokidar": "^3.3.0",
4088− "dependency-graph": "^0.11.0",
4089− "fs-extra": "^10.0.0",
4090− "get-stdin": "^9.0.0",
4091− "globby": "^12.0.0",
4092− "picocolors": "^1.0.0",
4093− "postcss-load-config": "^3.0.0",
4094− "postcss-reporter": "^7.0.0",
4095− "pretty-hrtime": "^1.0.3",
4096− "read-cache": "^1.0.0",
4097− "slash": "^4.0.0",
4098− "yargs": "^17.0.0"
4099− },
4100− "bin": {
4101− "postcss": "index.js"
4102− },
4103− "engines": {
4104− "node": ">=12"
4105− },
4106− "peerDependencies": {
4107− "postcss": "^8.0.0"
3597+ "requires": {
3598+ "path-key": "^3.1.0",
3599+ "shebang-command": "^2.0.0",
3600+ "which": "^2.0.1"
41083601 }
41093602 },
4110− "node_modules/postcss-cli/node_modules/yargs": {
4111− "version": "17.3.1",
4112− "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
4113− "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
4114− "dev": true,
4115− "dependencies": {
4116− "cliui": "^7.0.2",
4117− "escalade": "^3.1.1",
4118− "get-caller-file": "^2.0.5",
4119− "require-directory": "^2.1.1",
4120− "string-width": "^4.2.3",
4121− "y18n": "^5.0.5",
4122− "yargs-parser": "^21.0.0"
4123− },
4124− "engines": {
4125− "node": ">=12"
4126− }
3603+ "cssesc": {
3604+ "version": "3.0.0",
3605+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
3606+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
3607+ "dev": true
41273608 },
4128− "node_modules/postcss-cli/node_modules/yargs-parser": {
4129− "version": "21.0.0",
4130− "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz",
4131− "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==",
3609+ "date-fns": {
3610+ "version": "2.28.0",
3611+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz",
3612+ "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==",
3613+ "dev": true
3614+ },
3615+ "debug": {
3616+ "version": "4.3.3",
3617+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
3618+ "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
41323619 "dev": true,
4133− "engines": {
4134− "node": ">=12"
3620+ "requires": {
3621+ "ms": "2.1.2"
41353622 }
41363623 },
4137− "node_modules/postcss-js": {
4138− "version": "4.0.0",
4139− "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz",
4140− "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==",
4141− "dev": true,
4142− "dependencies": {
4143− "camelcase-css": "^2.0.1"
4144− },
4145− "engines": {
4146− "node": "^12 || ^14 || >= 16"
4147− },
4148− "funding": {
4149− "type": "opencollective",
4150− "url": "https://opencollective.com/postcss/"
4151− },
4152− "peerDependencies": {
4153− "postcss": "^8.3.3"
3624+ "deep-rename-keys": {
3625+ "version": "0.2.1",
3626+ "resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz",
3627+ "integrity": "sha512-RHd9ABw4Fvk+gYDWqwOftG849x0bYOySl/RgX0tLI9i27ZIeSO91mLZJEp7oPHOMFqHvpgu21YptmDt0FYD/0A==",
3628+ "requires": {
3629+ "kind-of": "^3.0.2",
3630+ "rename-keys": "^1.1.2"
41543631 }
41553632 },
4156− "node_modules/postcss-load-config": {
4157− "version": "3.1.1",
4158− "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.1.tgz",
4159− "integrity": "sha512-c/9XYboIbSEUZpiD1UQD0IKiUe8n9WHYV7YFe7X7J+ZwCsEKkUJSFWjS9hBU1RR9THR7jMXst8sxiqP0jjo2mg==",
3633+ "defined": {
3634+ "version": "1.0.0",
3635+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
3636+ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
3637+ "dev": true
3638+ },
3639+ "dependency-graph": {
3640+ "version": "0.11.0",
3641+ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
3642+ "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
3643+ "dev": true
3644+ },
3645+ "detect-indent": {
3646+ "version": "6.1.0",
3647+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
3648+ "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
3649+ "dev": true
3650+ },
3651+ "detective": {
3652+ "version": "5.2.0",
3653+ "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz",
3654+ "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==",
41603655 "dev": true,
4161− "dependencies": {
4162− "lilconfig": "^2.0.4",
4163− "yaml": "^1.10.2"
4164− },
4165− "engines": {
4166− "node": ">= 10"
4167− },
4168− "funding": {
4169− "type": "opencollective",
4170− "url": "https://opencollective.com/postcss/"
4171− },
4172− "peerDependencies": {
4173− "ts-node": ">=9.0.0"
4174− },
4175− "peerDependenciesMeta": {
4176− "ts-node": {
4177− "optional": true
4178− }
3656+ "requires": {
3657+ "acorn-node": "^1.6.1",
3658+ "defined": "^1.0.0",
3659+ "minimist": "^1.1.1"
41793660 }
41803661 },
4181− "node_modules/postcss-nested": {
4182− "version": "5.0.6",
4183− "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz",
4184− "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==",
3662+ "didyoumean": {
3663+ "version": "1.2.2",
3664+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
3665+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
3666+ "dev": true
3667+ },
3668+ "dir-glob": {
3669+ "version": "3.0.1",
3670+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
3671+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
41853672 "dev": true,
4186− "dependencies": {
4187− "postcss-selector-parser": "^6.0.6"
4188− },
4189− "engines": {
4190− "node": ">=12.0"
4191− },
4192− "funding": {
4193− "type": "opencollective",
4194− "url": "https://opencollective.com/postcss/"
4195− },
4196− "peerDependencies": {
4197− "postcss": "^8.2.14"
3673+ "requires": {
3674+ "path-type": "^4.0.0"
41983675 }
41993676 },
4200− "node_modules/postcss-reporter": {
4201− "version": "7.0.5",
4202− "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.5.tgz",
4203− "integrity": "sha512-glWg7VZBilooZGOFPhN9msJ3FQs19Hie7l5a/eE6WglzYqVeH3ong3ShFcp9kDWJT1g2Y/wd59cocf9XxBtkWA==",
3677+ "dlv": {
3678+ "version": "1.1.3",
3679+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
3680+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
3681+ "dev": true
3682+ },
3683+ "dotenv": {
3684+ "version": "16.0.1",
3685+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
3686+ "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==",
3687+ "dev": true
3688+ },
3689+ "dotenv-cli": {
3690+ "version": "6.0.0",
3691+ "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-6.0.0.tgz",
3692+ "integrity": "sha512-qXlCOi3UMDhCWFKe0yq5sg3X+pJAz+RQDiFN38AMSbUrnY3uZshSfDJUAge951OS7J9gwLZGfsBlWRSOYz/TRg==",
42043693 "dev": true,
4205− "dependencies": {
4206− "picocolors": "^1.0.0",
4207− "thenby": "^1.3.4"
4208− },
4209− "engines": {
4210− "node": ">=10"
4211− },
4212− "funding": {
4213− "type": "opencollective",
4214− "url": "https://opencollective.com/postcss/"
4215− },
4216− "peerDependencies": {
4217− "postcss": "^8.1.0"
3694+ "requires": {
3695+ "cross-spawn": "^7.0.3",
3696+ "dotenv": "^16.0.0",
3697+ "dotenv-expand": "^8.0.1",
3698+ "minimist": "^1.2.5"
42183699 }
42193700 },
4220− "node_modules/postcss-selector-parser": {
4221− "version": "6.0.8",
4222− "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz",
4223− "integrity": "sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==",
4224− "dev": true,
4225− "dependencies": {
4226− "cssesc": "^3.0.0",
4227− "util-deprecate": "^1.0.2"
4228− },
4229− "engines": {
4230− "node": ">=4"
4231− }
3701+ "dotenv-expand": {
3702+ "version": "8.0.3",
3703+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz",
3704+ "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==",
3705+ "dev": true
42323706 },
4233− "node_modules/postcss-value-parser": {
4234− "version": "4.2.0",
4235− "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
4236− "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
3707+ "electron-to-chromium": {
3708+ "version": "1.4.38",
3709+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.38.tgz",
3710+ "integrity": "sha512-WhHt3sZazKj0KK/UpgsbGQnUUoFeAHVishzHFExMxagpZgjiGYSC9S0ZlbhCfSH2L2i+2A1yyqOIliTctMx7KQ==",
42373711 "dev": true
42383712 },
4239− "node_modules/pretty-hrtime": {
4240− "version": "1.0.3",
4241− "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
4242− "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
3713+ "emoji-regex": {
3714+ "version": "8.0.0",
3715+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
3716+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
3717+ "dev": true
3718+ },
3719+ "error-ex": {
3720+ "version": "1.3.2",
3721+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
3722+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
42433723 "dev": true,
4244− "engines": {
4245− "node": ">= 0.8"
3724+ "requires": {
3725+ "is-arrayish": "^0.2.1"
42463726 }
42473727 },
4248− "node_modules/queue-microtask": {
4249− "version": "1.2.3",
4250− "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
4251− "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
4252− "dev": true,
4253− "funding": [
4254− {
4255− "type": "github",
4256− "url": "https://github.com/sponsors/feross"
4257− },
4258− {
4259− "type": "patreon",
4260− "url": "https://www.patreon.com/feross"
4261− },
4262− {
4263− "type": "consulting",
4264− "url": "https://feross.org/support"
4265− }
4266− ]
3728+ "es6-promise": {
3729+ "version": "3.3.1",
3730+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
3731+ "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=",
3732+ "dev": true
42673733 },
4268− "node_modules/quick-lru": {
4269− "version": "5.1.1",
4270− "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
4271− "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
3734+ "esbuild": {
3735+ "version": "0.13.15",
3736+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.15.tgz",
3737+ "integrity": "sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==",
42723738 "dev": true,
4273− "engines": {
4274− "node": ">=10"
4275− },
4276− "funding": {
4277− "url": "https://github.com/sponsors/sindresorhus"
4278− }
4279− },
4280− "node_modules/react": {
4281− "version": "17.0.2",
4282− "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
4283− "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
4284− "peer": true,
4285− "dependencies": {
4286− "loose-envify": "^1.1.0",
4287− "object-assign": "^4.1.1"
4288− },
4289− "engines": {
4290− "node": ">=0.10.0"
3739+ "requires": {
3740+ "esbuild-android-arm64": "0.13.15",
3741+ "esbuild-darwin-64": "0.13.15",
3742+ "esbuild-darwin-arm64": "0.13.15",
3743+ "esbuild-freebsd-64": "0.13.15",
3744+ "esbuild-freebsd-arm64": "0.13.15",
3745+ "esbuild-linux-32": "0.13.15",
3746+ "esbuild-linux-64": "0.13.15",
3747+ "esbuild-linux-arm": "0.13.15",
3748+ "esbuild-linux-arm64": "0.13.15",
3749+ "esbuild-linux-mips64le": "0.13.15",
3750+ "esbuild-linux-ppc64le": "0.13.15",
3751+ "esbuild-netbsd-64": "0.13.15",
3752+ "esbuild-openbsd-64": "0.13.15",
3753+ "esbuild-sunos-64": "0.13.15",
3754+ "esbuild-windows-32": "0.13.15",
3755+ "esbuild-windows-64": "0.13.15",
3756+ "esbuild-windows-arm64": "0.13.15"
42913757 }
42923758 },
4293− "node_modules/read-cache": {
4294− "version": "1.0.0",
4295− "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
4296− "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
3759+ "esbuild-android-arm64": {
3760+ "version": "0.13.15",
3761+ "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz",
3762+ "integrity": "sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg==",
42973763 "dev": true,
4298− "dependencies": {
4299− "pify": "^2.3.0"
4300− }
3764+ "optional": true
43013765 },
4302− "node_modules/readdirp": {
4303− "version": "3.6.0",
4304− "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
4305− "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
4306− "dependencies": {
4307− "picomatch": "^2.2.1"
4308− },
4309− "engines": {
4310− "node": ">=8.10.0"
4311− }
3766+ "esbuild-darwin-64": {
3767+ "version": "0.13.15",
3768+ "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz",
3769+ "integrity": "sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==",
3770+ "dev": true,
3771+ "optional": true
43123772 },
4313− "node_modules/regenerator-runtime": {
4314− "version": "0.13.9",
4315− "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
4316− "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
3773+ "esbuild-darwin-arm64": {
3774+ "version": "0.13.15",
3775+ "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz",
3776+ "integrity": "sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==",
3777+ "dev": true,
3778+ "optional": true
43173779 },
4318− "node_modules/regexparam": {
4319− "version": "2.0.0",
4320− "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-2.0.0.tgz",
4321− "integrity": "sha512-gJKwd2MVPWHAIFLsaYDZfyKzHNS4o7E/v8YmNf44vmeV2e4YfVoDToTOKTvE7ab68cRJ++kLuEXJBaEeJVt5ow==",
3780+ "esbuild-freebsd-64": {
3781+ "version": "0.13.15",
3782+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz",
3783+ "integrity": "sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==",
43223784 "dev": true,
4323− "engines": {
4324− "node": ">=8"
4325− }
3785+ "optional": true
43263786 },
4327− "node_modules/rename-keys": {
4328− "version": "1.2.0",
4329− "resolved": "https://registry.npmjs.org/rename-keys/-/rename-keys-1.2.0.tgz",
4330− "integrity": "sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg==",
4331− "engines": {
4332− "node": ">= 0.8.0"
4333− }
3787+ "esbuild-freebsd-arm64": {
3788+ "version": "0.13.15",
3789+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz",
3790+ "integrity": "sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==",
3791+ "dev": true,
3792+ "optional": true
43343793 },
4335− "node_modules/require-directory": {
4336− "version": "2.1.1",
4337− "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
4338− "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
3794+ "esbuild-linux-32": {
3795+ "version": "0.13.15",
3796+ "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz",
3797+ "integrity": "sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==",
43393798 "dev": true,
4340− "engines": {
4341− "node": ">=0.10.0"
4342− }
3799+ "optional": true
43433800 },
4344− "node_modules/require-relative": {
4345− "version": "0.8.7",
4346− "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz",
4347− "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=",
4348− "dev": true
3801+ "esbuild-linux-64": {
3802+ "version": "0.13.15",
3803+ "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz",
3804+ "integrity": "sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==",
3805+ "dev": true,
3806+ "optional": true
43493807 },
4350− "node_modules/resolve": {
4351− "version": "1.21.0",
4352− "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz",
4353− "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==",
3808+ "esbuild-linux-arm": {
3809+ "version": "0.13.15",
3810+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz",
3811+ "integrity": "sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==",
43543812 "dev": true,
4355− "dependencies": {
4356− "is-core-module": "^2.8.0",
4357− "path-parse": "^1.0.7",
4358− "supports-preserve-symlinks-flag": "^1.0.0"
4359− },
4360− "bin": {
4361− "resolve": "bin/resolve"
4362− },
4363− "funding": {
4364− "url": "https://github.com/sponsors/ljharb"
4365− }
3813+ "optional": true
43663814 },
4367− "node_modules/resolve-from": {
4368− "version": "4.0.0",
4369− "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
4370− "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
3815+ "esbuild-linux-arm64": {
3816+ "version": "0.13.15",
3817+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz",
3818+ "integrity": "sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==",
43713819 "dev": true,
4372− "engines": {
4373− "node": ">=4"
4374− }
3820+ "optional": true
43753821 },
4376− "node_modules/reusify": {
4377− "version": "1.0.4",
4378− "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
4379− "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
3822+ "esbuild-linux-mips64le": {
3823+ "version": "0.13.15",
3824+ "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz",
3825+ "integrity": "sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==",
43803826 "dev": true,
4381− "engines": {
4382− "iojs": ">=1.0.0",
4383− "node": ">=0.10.0"
4384− }
3827+ "optional": true
43853828 },
4386− "node_modules/rimraf": {
4387− "version": "2.7.1",
4388− "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
4389− "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
3829+ "esbuild-linux-ppc64le": {
3830+ "version": "0.13.15",
3831+ "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz",
3832+ "integrity": "sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==",
43903833 "dev": true,
4391− "dependencies": {
4392− "glob": "^7.1.3"
4393− },
4394− "bin": {
4395− "rimraf": "bin.js"
4396− }
3834+ "optional": true
43973835 },
4398− "node_modules/rollup": {
4399− "version": "2.63.0",
4400− "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.63.0.tgz",
4401− "integrity": "sha512-nps0idjmD+NXl6OREfyYXMn/dar3WGcyKn+KBzPdaLecub3x/LrId0wUcthcr8oZUAcZAR8NKcfGGFlNgGL1kQ==",
3836+ "esbuild-netbsd-64": {
3837+ "version": "0.13.15",
3838+ "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz",
3839+ "integrity": "sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==",
44023840 "dev": true,
4403− "bin": {
4404− "rollup": "dist/bin/rollup"
4405− },
4406− "engines": {
4407− "node": ">=10.0.0"
4408− },
4409− "optionalDependencies": {
4410− "fsevents": "~2.3.2"
4411− }
3841+ "optional": true
44123842 },
4413− "node_modules/run-parallel": {
4414− "version": "1.2.0",
4415− "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
4416− "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
3843+ "esbuild-openbsd-64": {
3844+ "version": "0.13.15",
3845+ "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz",
3846+ "integrity": "sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==",
44173847 "dev": true,
4418− "funding": [
4419− {
4420− "type": "github",
4421− "url": "https://github.com/sponsors/feross"
4422− },
4423− {
4424− "type": "patreon",
4425− "url": "https://www.patreon.com/feross"
4426− },
4427− {
4428− "type": "consulting",
4429− "url": "https://feross.org/support"
4430− }
4431− ],
4432− "dependencies": {
4433− "queue-microtask": "^1.2.2"
4434− }
3848+ "optional": true
44353849 },
4436− "node_modules/rxjs": {
4437− "version": "6.6.7",
4438− "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
4439− "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
3850+ "esbuild-sunos-64": {
3851+ "version": "0.13.15",
3852+ "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz",
3853+ "integrity": "sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==",
44403854 "dev": true,
4441− "dependencies": {
4442− "tslib": "^1.9.0"
4443− },
4444− "engines": {
4445− "npm": ">=2.0.0"
4446− }
3855+ "optional": true
44473856 },
4448− "node_modules/rxjs/node_modules/tslib": {
4449− "version": "1.14.1",
4450− "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
4451− "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
4452− "dev": true
3857+ "esbuild-windows-32": {
3858+ "version": "0.13.15",
3859+ "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz",
3860+ "integrity": "sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==",
3861+ "dev": true,
3862+ "optional": true
44533863 },
4454− "node_modules/sade": {
4455− "version": "1.8.1",
4456− "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
4457− "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
3864+ "esbuild-windows-64": {
3865+ "version": "0.13.15",
3866+ "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz",
3867+ "integrity": "sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==",
44583868 "dev": true,
4459− "dependencies": {
4460− "mri": "^1.1.0"
4461− },
4462− "engines": {
4463− "node": ">=6"
4464− }
3869+ "optional": true
44653870 },
4466− "node_modules/sander": {
4467− "version": "0.5.1",
4468− "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz",
4469− "integrity": "sha1-dB4kXiMfB8r7b98PEzrfohalAq0=",
3871+ "esbuild-windows-arm64": {
3872+ "version": "0.13.15",
3873+ "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz",
3874+ "integrity": "sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==",
44703875 "dev": true,
4471− "dependencies": {
4472− "es6-promise": "^3.1.2",
4473− "graceful-fs": "^4.1.3",
4474− "mkdirp": "^0.5.1",
4475− "rimraf": "^2.5.2"
4476− }
3876+ "optional": true
44773877 },
4478− "node_modules/sass": {
4479− "version": "1.50.0",
4480− "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz",
4481− "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==",
4482− "dependencies": {
4483− "chokidar": ">=3.0.0 <4.0.0",
4484− "immutable": "^4.0.0",
4485− "source-map-js": ">=0.6.2 <2.0.0"
4486− },
4487− "bin": {
4488− "sass": "sass.js"
4489− },
4490− "engines": {
4491− "node": ">=12.0.0"
4492− }
3878+ "escalade": {
3879+ "version": "3.1.1",
3880+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
3881+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
3882+ "dev": true
44933883 },
4494− "node_modules/shebang-command": {
4495− "version": "2.0.0",
4496− "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
4497− "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
3884+ "escape-string-regexp": {
3885+ "version": "1.0.5",
3886+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
3887+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
3888+ "dev": true
3889+ },
3890+ "estree-walker": {
3891+ "version": "2.0.2",
3892+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
3893+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
3894+ "dev": true
3895+ },
3896+ "eventemitter3": {
3897+ "version": "2.0.3",
3898+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
3899+ "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
3900+ },
3901+ "events": {
3902+ "version": "3.3.0",
3903+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
3904+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="
3905+ },
3906+ "fast-glob": {
3907+ "version": "3.2.9",
3908+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.9.tgz",
3909+ "integrity": "sha512-MBwILhhD92sziIrMQwpqcuGERF+BH99ei2a3XsGJuqEKcSycAL+w0HWokFenZXona+kjFr82Lf71eTxNRC06XQ==",
44983910 "dev": true,
4499− "dependencies": {
4500− "shebang-regex": "^3.0.0"
4501− },
4502− "engines": {
4503− "node": ">=8"
3911+ "requires": {
3912+ "@nodelib/fs.stat": "^2.0.2",
3913+ "@nodelib/fs.walk": "^1.2.3",
3914+ "glob-parent": "^5.1.2",
3915+ "merge2": "^1.3.0",
3916+ "micromatch": "^4.0.4"
45043917 }
45053918 },
4506− "node_modules/shebang-regex": {
4507− "version": "3.0.0",
4508− "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
4509− "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
3919+ "fastq": {
3920+ "version": "1.13.0",
3921+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
3922+ "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
45103923 "dev": true,
4511− "engines": {
4512− "node": ">=8"
3924+ "requires": {
3925+ "reusify": "^1.0.4"
45133926 }
45143927 },
4515− "node_modules/slash": {
4516− "version": "4.0.0",
4517− "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
4518− "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
3928+ "fill-range": {
3929+ "version": "7.0.1",
3930+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
3931+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
45193932 "dev": true,
4520− "engines": {
4521− "node": ">=12"
4522− },
4523− "funding": {
4524− "url": "https://github.com/sponsors/sindresorhus"
3933+ "requires": {
3934+ "to-regex-range": "^5.0.1"
45253935 }
45263936 },
4527− "node_modules/sorcery": {
4528− "version": "0.10.0",
4529− "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz",
4530− "integrity": "sha1-iukK19fLBfxZ8asMY3hF1cFaUrc=",
3937+ "fraction.js": {
3938+ "version": "4.1.2",
3939+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz",
3940+ "integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==",
3941+ "dev": true
3942+ },
3943+ "fs-extra": {
3944+ "version": "10.0.0",
3945+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
3946+ "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
45313947 "dev": true,
4532− "dependencies": {
4533− "buffer-crc32": "^0.2.5",
4534− "minimist": "^1.2.0",
4535− "sander": "^0.5.0",
4536− "sourcemap-codec": "^1.3.0"
4537− },
4538− "bin": {
4539− "sorcery": "bin/index.js"
3948+ "requires": {
3949+ "graceful-fs": "^4.2.0",
3950+ "jsonfile": "^6.0.1",
3951+ "universalify": "^2.0.0"
45403952 }
45413953 },
4542− "node_modules/source-map": {
4543− "version": "0.7.3",
4544− "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
4545− "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
3954+ "fs.realpath": {
3955+ "version": "1.0.0",
3956+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
3957+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
3958+ "dev": true
3959+ },
3960+ "fsevents": {
3961+ "version": "2.3.2",
3962+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
3963+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
45463964 "dev": true,
4547− "engines": {
4548− "node": ">= 8"
4549− }
3965+ "optional": true
45503966 },
4551− "node_modules/source-map-js": {
4552− "version": "1.0.1",
4553− "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
4554− "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
4555− "engines": {
4556− "node": ">=0.10.0"
4557− }
3967+ "function-bind": {
3968+ "version": "1.1.1",
3969+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
3970+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
3971+ "dev": true
45583972 },
4559− "node_modules/sourcemap-codec": {
4560− "version": "1.4.8",
4561− "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
4562− "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
3973+ "get-caller-file": {
3974+ "version": "2.0.5",
3975+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
3976+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
45633977 "dev": true
45643978 },
4565− "node_modules/spawn-command": {
4566− "version": "0.0.2-1",
4567− "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
4568− "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=",
3979+ "get-stdin": {
3980+ "version": "9.0.0",
3981+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
3982+ "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
45693983 "dev": true
45703984 },
4571− "node_modules/string-width": {
4572− "version": "4.2.3",
4573− "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
4574− "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
4575− "dev": true,
4576− "dependencies": {
4577− "emoji-regex": "^8.0.0",
4578− "is-fullwidth-code-point": "^3.0.0",
4579− "strip-ansi": "^6.0.1"
4580− },
4581− "engines": {
4582− "node": ">=8"
4583− }
3985+ "get-value": {
3986+ "version": "2.0.6",
3987+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
3988+ "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA=="
45843989 },
4585− "node_modules/strip-ansi": {
4586− "version": "6.0.1",
4587− "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
4588− "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
3990+ "glob": {
3991+ "version": "7.2.0",
3992+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
3993+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
45893994 "dev": true,
4590− "dependencies": {
4591− "ansi-regex": "^5.0.1"
4592− },
4593− "engines": {
4594− "node": ">=8"
3995+ "requires": {
3996+ "fs.realpath": "^1.0.0",
3997+ "inflight": "^1.0.4",
3998+ "inherits": "2",
3999+ "minimatch": "^3.0.4",
4000+ "once": "^1.3.0",
4001+ "path-is-absolute": "^1.0.0"
45954002 }
45964003 },
4597− "node_modules/strip-indent": {
4598− "version": "3.0.0",
4599− "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
4600− "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
4004+ "glob-parent": {
4005+ "version": "5.1.2",
4006+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
4007+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
46014008 "dev": true,
4602− "dependencies": {
4603− "min-indent": "^1.0.0"
4604− },
4605− "engines": {
4606− "node": ">=8"
4009+ "requires": {
4010+ "is-glob": "^4.0.1"
46074011 }
46084012 },
4609− "node_modules/supports-color": {
4610− "version": "7.2.0",
4611− "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
4612− "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
4013+ "globby": {
4014+ "version": "12.0.2",
4015+ "resolved": "https://registry.npmjs.org/globby/-/globby-12.0.2.tgz",
4016+ "integrity": "sha512-lAsmb/5Lww4r7MM9nCCliDZVIKbZTavrsunAsHLr9oHthrZP1qi7/gAnHOsUs9bLvEt2vKVJhHmxuL7QbDuPdQ==",
46134017 "dev": true,
4614− "dependencies": {
4615− "has-flag": "^4.0.0"
4616− },
4617− "engines": {
4618− "node": ">=8"
4018+ "requires": {
4019+ "array-union": "^3.0.1",
4020+ "dir-glob": "^3.0.1",
4021+ "fast-glob": "^3.2.7",
4022+ "ignore": "^5.1.8",
4023+ "merge2": "^1.4.1",
4024+ "slash": "^4.0.0"
46194025 }
46204026 },
4621− "node_modules/supports-preserve-symlinks-flag": {
4622− "version": "1.0.0",
4623− "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
4624− "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
4625− "dev": true,
4626− "engines": {
4627− "node": ">= 0.4"
4628− },
4629− "funding": {
4630− "url": "https://github.com/sponsors/ljharb"
4027+ "graceful-fs": {
4028+ "version": "4.2.9",
4029+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
4030+ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
4031+ "dev": true
4032+ },
4033+ "graphology": {
4034+ "version": "0.24.1",
4035+ "resolved": "https://registry.npmjs.org/graphology/-/graphology-0.24.1.tgz",
4036+ "integrity": "sha512-6lNz1PNTAe9Q6ioHKrXu0Lp047sgvOoHa4qmP/8mnJWCGv2iIZPQkuHPUb2/OWDWCqHpw2hKgJLJ55X/66xmHg==",
4037+ "requires": {
4038+ "events": "^3.3.0",
4039+ "obliterator": "^2.0.2"
46314040 }
46324041 },
4633− "node_modules/svelte": {
4634− "version": "3.45.0",
4635− "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.45.0.tgz",
4636− "integrity": "sha512-6AWftH2eqqKLYH1HvKpuUWe8OfjflarhegN57P/Cqwc2Rb2F5oIdDtANU/jMscyZMzG0v6nTQox0siZR9cmRVQ==",
4042+ "graphology-types": {
4043+ "version": "0.24.4",
4044+ "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.4.tgz",
4045+ "integrity": "sha512-CSgmycWiviCctMFO86YoUTJN1t4/PLKC5Pos2Hite+7kCUXTr+mGlDUAOgpcKG1IfFaeL9VDmTjFpzs2rTnPWw==",
4046+ "peer": true
4047+ },
4048+ "graphology-utils": {
4049+ "version": "2.5.2",
4050+ "resolved": "https://registry.npmjs.org/graphology-utils/-/graphology-utils-2.5.2.tgz",
4051+ "integrity": "sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==",
4052+ "requires": {}
4053+ },
4054+ "has": {
4055+ "version": "1.0.3",
4056+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
4057+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
46374058 "dev": true,
4638− "engines": {
4639− "node": ">= 8"
4059+ "requires": {
4060+ "function-bind": "^1.1.1"
46404061 }
46414062 },
4642− "node_modules/svelte-check": {
4643− "version": "2.2.11",
4644− "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-2.2.11.tgz",
4645− "integrity": "sha512-clotPGGZPj3LuS9qP1lk+Wwnsj+js42ehCPmHk+qtyaQh/dU95e0qkpPmtmOMYHN6My5Y75XqeN1QNLj5V5gwA==",
4646− "dev": true,
4647− "dependencies": {
4648− "chalk": "^4.0.0",
4649− "chokidar": "^3.4.1",
4650− "fast-glob": "^3.2.7",
4651− "import-fresh": "^3.2.1",
4652− "minimist": "^1.2.5",
4653− "sade": "^1.7.4",
4654− "source-map": "^0.7.3",
4655− "svelte-preprocess": "^4.0.0",
4656− "typescript": "*"
4657− },
4658− "bin": {
4659− "svelte-check": "bin/svelte-check"
4063+ "has-flag": {
4064+ "version": "4.0.0",
4065+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
4066+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
4067+ "dev": true
4068+ },
4069+ "has-value": {
4070+ "version": "0.3.1",
4071+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
4072+ "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==",
4073+ "requires": {
4074+ "get-value": "^2.0.3",
4075+ "has-values": "^0.1.4",
4076+ "isobject": "^2.0.0"
46604077 },
4661− "peerDependencies": {
4662− "svelte": "^3.24.0"
4078+ "dependencies": {
4079+ "isobject": {
4080+ "version": "2.1.0",
4081+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
4082+ "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==",
4083+ "requires": {
4084+ "isarray": "1.0.0"
4085+ }
4086+ }
46634087 }
46644088 },
4665− "node_modules/svelte-copy-to-clipboard": {
4666− "version": "0.2.5",
4667− "resolved": "https://registry.npmjs.org/svelte-copy-to-clipboard/-/svelte-copy-to-clipboard-0.2.5.tgz",
4668− "integrity": "sha512-EAULxib4pRa59nyz25dDKITgSAVkrNVojRZVCSO8MIFd5GJljghJaCTIe/7R+O3GxKYIwJ3XHDNoY1hfjJeyEg=="
4089+ "has-values": {
4090+ "version": "0.1.4",
4091+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
4092+ "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ=="
46694093 },
4670− "node_modules/svelte-hmr": {
4671− "version": "0.14.9",
4672− "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.14.9.tgz",
4673− "integrity": "sha512-bKE9+4qb4sAnA+TKHiYurUl970rjA0XmlP9TEP7K/ncyWz3m81kA4HOgmlZK/7irGK7gzZlaPDI3cmf8fp/+tg==",
4674− "dev": true,
4675− "peerDependencies": {
4676− "svelte": ">=3.19.0"
4677− }
4094+ "ignore": {
4095+ "version": "5.2.0",
4096+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
4097+ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
4098+ "dev": true
46784099 },
4679− "node_modules/svelte-preprocess": {
4680− "version": "4.10.1",
4681− "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.10.1.tgz",
4682− "integrity": "sha512-NSNloaylf+o9UeyUR2KvpdxrAyMdHl3U7rMnoP06/sG0iwJvlUM4TpMno13RaNqovh4AAoGsx1jeYcIyuGUXMw==",
4100+ "immer": {
4101+ "version": "9.0.7",
4102+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.7.tgz",
4103+ "integrity": "sha512-KGllzpbamZDvOIxnmJ0jI840g7Oikx58lBPWV0hUh7dtAyZpFqqrBZdKka5GlTwMTZ1Tjc/bKKW4VSFAt6BqMA=="
4104+ },
4105+ "immutable": {
4106+ "version": "4.0.0",
4107+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
4108+ "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
4109+ "dev": true
4110+ },
4111+ "import-fresh": {
4112+ "version": "3.3.0",
4113+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
4114+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
46834115 "dev": true,
4684− "hasInstallScript": true,
4685− "dependencies": {
4686− "@types/pug": "^2.0.4",
4687− "@types/sass": "^1.16.0",
4688− "detect-indent": "^6.0.0",
4689− "magic-string": "^0.25.7",
4690− "sorcery": "^0.10.0",
4691− "strip-indent": "^3.0.0"
4692− },
4693− "engines": {
4694− "node": ">= 9.11.2"
4695− },
4696− "peerDependencies": {
4697− "@babel/core": "^7.10.2",
4698− "coffeescript": "^2.5.1",
4699− "less": "^3.11.3",
4700− "postcss": "^7 || ^8",
4701− "postcss-load-config": "^2.1.0 || ^3.0.0",
4702− "pug": "^3.0.0",
4703− "sass": "^1.26.8",
4704− "stylus": "^0.54.7",
4705− "sugarss": "^2.0.0",
4706− "svelte": "^3.23.0",
4707− "typescript": "^4.5.2"
4708− },
4709− "peerDependenciesMeta": {
4710− "@babel/core": {
4711− "optional": true
4712− },
4713− "coffeescript": {
4714− "optional": true
4715− },
4716− "less": {
4717− "optional": true
4718− },
4719− "node-sass": {
4720− "optional": true
4721− },
4722− "postcss": {
4723− "optional": true
4724− },
4725− "postcss-load-config": {
4726− "optional": true
4727− },
4728− "pug": {
4729− "optional": true
4730− },
4731− "sass": {
4732− "optional": true
4733− },
4734− "stylus": {
4735− "optional": true
4736− },
4737− "sugarss": {
4738− "optional": true
4739− },
4740− "typescript": {
4741− "optional": true
4742− }
4116+ "requires": {
4117+ "parent-module": "^1.0.0",
4118+ "resolve-from": "^4.0.0"
47434119 }
47444120 },
4745− "node_modules/svelte-spa-router": {
4746− "version": "3.2.0",
4747− "resolved": "https://registry.npmjs.org/svelte-spa-router/-/svelte-spa-router-3.2.0.tgz",
4748− "integrity": "sha512-igemo5Vs82TGBBw+DjWt6qKameXYzNs6aDXcTxou5XbEvOjiRcAM6MLkdVRCatn6u8r42dE99bt/br7T4qe/AQ==",
4121+ "inflight": {
4122+ "version": "1.0.6",
4123+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
4124+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
47494125 "dev": true,
4750− "dependencies": {
4751− "regexparam": "2.0.0"
4752− },
4753− "funding": {
4754− "url": "https://github.com/sponsors/ItalyPaleAle"
4126+ "requires": {
4127+ "once": "^1.3.0",
4128+ "wrappy": "1"
47554129 }
47564130 },
4757− "node_modules/svgson": {
4758− "version": "4.1.0",
4759− "resolved": "https://registry.npmjs.org/svgson/-/svgson-4.1.0.tgz",
4760− "integrity": "sha512-DodISxHtdLKUghDYA+PGK4Qq350+CbBAkdvGLkBFSmWd9WKSg4dijgjB1IiRPTmsUCd+a7KYe+ILHtklYgQyzQ==",
4761− "dependencies": {
4762− "deep-rename-keys": "^0.2.1",
4763− "omit-deep": "0.3.0",
4764− "xml-reader": "2.4.3"
4765− }
4766− },
4767− "node_modules/tailwindcss": {
4768− "version": "3.0.12",
4769− "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.12.tgz",
4770− "integrity": "sha512-VqhF86z2c34sJyS5ZS8Q2nYuN0KzqZw1GGsuQQO9kJ3mY1oG7Fsag0vICkxUVXk6P+1sUkTkjMjKWCjEF0hNHw==",
4771− "dev": true,
4772− "dependencies": {
4773− "arg": "^5.0.1",
4774− "chalk": "^4.1.2",
4775− "chokidar": "^3.5.2",
4776− "color-name": "^1.1.4",
4777− "cosmiconfig": "^7.0.1",
4778− "detective": "^5.2.0",
4779− "didyoumean": "^1.2.2",
4780− "dlv": "^1.1.3",
4781− "fast-glob": "^3.2.7",
4782− "glob-parent": "^6.0.2",
4783− "is-glob": "^4.0.3",
4784− "normalize-path": "^3.0.0",
4785− "object-hash": "^2.2.0",
4786− "postcss-js": "^4.0.0",
4787− "postcss-load-config": "^3.1.0",
4788− "postcss-nested": "5.0.6",
4789− "postcss-selector-parser": "^6.0.8",
4790− "postcss-value-parser": "^4.2.0",
4791− "quick-lru": "^5.1.1",
4792− "resolve": "^1.20.0"
4793− },
4794− "bin": {
4795− "tailwind": "lib/cli.js",
4796− "tailwindcss": "lib/cli.js"
4797− },
4798− "engines": {
4799− "node": ">=12.13.0"
4800− },
4801− "peerDependencies": {
4802− "autoprefixer": "^10.0.2",
4803− "postcss": "^8.0.9"
4804− }
4805− },
4806− "node_modules/tailwindcss/node_modules/glob-parent": {
4807− "version": "6.0.2",
4808− "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
4809− "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
4810− "dev": true,
4811− "dependencies": {
4812− "is-glob": "^4.0.3"
4813− },
4814− "engines": {
4815− "node": ">=10.13.0"
4816− }
4817− },
4818− "node_modules/thenby": {
4819− "version": "1.3.4",
4820− "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz",
4821− "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==",
4822− "dev": true
4823− },
4824− "node_modules/tippy.js": {
4825− "version": "6.3.7",
4826− "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
4827− "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
4828− "dependencies": {
4829− "@popperjs/core": "^2.9.0"
4830− }
4831− },
4832− "node_modules/to-regex-range": {
4833− "version": "5.0.1",
4834− "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
4835− "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
4836− "dependencies": {
4837− "is-number": "^7.0.0"
4838− },
4839− "engines": {
4840− "node": ">=8.0"
4841− }
4842− },
4843− "node_modules/transformation-matrix": {
4844− "version": "2.1.1",
4845− "resolved": "https://registry.npmjs.org/transformation-matrix/-/transformation-matrix-2.1.1.tgz",
4846− "integrity": "sha512-74MoNHhwLVuzwaPDcAecFjSkOA9vwWqyOdkeB0Be8Jc/IWSS5SNZKapFllqzkTliqZptkvqX5CZnVeDvfhN8cw=="
4847− },
4848− "node_modules/tree-kill": {
4849− "version": "1.2.2",
4850− "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
4851− "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
4852− "dev": true,
4853− "bin": {
4854− "tree-kill": "cli.js"
4855− }
4856− },
4857− "node_modules/tslib": {
4858− "version": "2.3.1",
4859− "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
4860− "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
4861− "dev": true
4862− },
4863− "node_modules/typescript": {
4864− "version": "4.5.4",
4865− "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
4866− "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
4867− "dev": true,
4868− "bin": {
4869− "tsc": "bin/tsc",
4870− "tsserver": "bin/tsserver"
4871− },
4872− "engines": {
4873− "node": ">=4.2.0"
4874− }
4875− },
4876− "node_modules/universalify": {
4877− "version": "2.0.0",
4878− "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
4879− "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
4880− "dev": true,
4881− "engines": {
4882− "node": ">= 10.0.0"
4883− }
4884− },
4885− "node_modules/unset-value": {
4886− "version": "0.1.2",
4887− "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz",
4888− "integrity": "sha1-UGgQuGfyfCpabpsEgzYx9t5Y0xA=",
4889− "dependencies": {
4890− "has-value": "^0.3.1",
4891− "isobject": "^3.0.0"
4892− },
4893− "engines": {
4894− "node": ">=0.10.0"
4895− }
4896− },
4897− "node_modules/urbit-ob": {
4898− "version": "5.0.1",
4899− "resolved": "https://registry.npmjs.org/urbit-ob/-/urbit-ob-5.0.1.tgz",
4900− "integrity": "sha512-qGNAwu87XNkW3g8ah4fUwmh2EKXtsdhEbyEiE5qX4Op17rhLH3HSkvu8g9z+MhqX51Uz9sf8ktvqJj/IRwETIQ==",
4901− "dependencies": {
4902− "bn.js": "^4.11.8",
4903− "lodash.chunk": "^4.2.0",
4904− "lodash.isequal": "^4.5.0"
4905− }
4906− },
4907− "node_modules/urbit-ob/node_modules/bn.js": {
4908− "version": "4.12.0",
4909− "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
4910− "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
4911− },
4912− "node_modules/util-deprecate": {
4913− "version": "1.0.2",
4914− "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
4915− "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
4131+ "inherits": {
4132+ "version": "2.0.4",
4133+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
4134+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
49164135 "dev": true
49174136 },
4918− "node_modules/vite": {
4919− "version": "2.7.10",
4920− "resolved": "https://registry.npmjs.org/vite/-/vite-2.7.10.tgz",
4921− "integrity": "sha512-KEY96ntXUid1/xJihJbgmLZx7QSC2D4Tui0FdS0Old5OokYzFclcofhtxtjDdGOk/fFpPbHv9yw88+rB93Tb8w==",
4922− "dev": true,
4923− "dependencies": {
4924− "esbuild": "^0.13.12",
4925− "postcss": "^8.4.5",
4926− "resolve": "^1.20.0",
4927− "rollup": "^2.59.0"
4928− },
4929− "bin": {
4930− "vite": "bin/vite.js"
4931− },
4932− "engines": {
4933− "node": ">=12.2.0"
4934− },
4935− "optionalDependencies": {
4936− "fsevents": "~2.3.2"
4937− },
4938− "peerDependencies": {
4939− "less": "*",
4940− "sass": "*",
4941− "stylus": "*"
4942− },
4943− "peerDependenciesMeta": {
4944− "less": {
4945− "optional": true
4946− },
4947− "sass": {
4948− "optional": true
4949− },
4950− "stylus": {
4951− "optional": true
4952− }
4953− }
4954− },
4955− "node_modules/vite-plugin-html-config": {
4956− "version": "1.0.8",
4957− "resolved": "https://registry.npmjs.org/vite-plugin-html-config/-/vite-plugin-html-config-1.0.8.tgz",
4958− "integrity": "sha512-3tTtBQO+6zpC8uzAAfj3FWygj+V6H6F9fEt5KtB3j5UHsRYP0yLpTHsMvubXtqCXbKDp1oOakYYSjprqYcbrpA==",
4959− "dev": true,
4960− "engines": {
4961− "node": ">=12.0.0"
4962− },
4963− "peerDependencies": {
4964− "vite": "^2.0.5"
4965− }
4966− },
4967− "node_modules/vite-plugin-rewrite-all": {
4968− "version": "0.1.2",
4969− "resolved": "https://registry.npmjs.org/vite-plugin-rewrite-all/-/vite-plugin-rewrite-all-0.1.2.tgz",
4970− "integrity": "sha512-hBFuG043kbixgZ/ke9SzKhkO6P8a5ryxD0CmZTe+/Cz17RIKi7uSeNUJy79V4FgavZ7pWVRg0tqVwJ7lP/A2/Q==",
4971− "dev": true,
4972− "dependencies": {
4973− "connect-history-api-fallback": "^1.6.0"
4974− },
4975− "engines": {
4976− "node": ">=12.0.0"
4977− },
4978− "peerDependencies": {
4979− "vite": "^2.0.2"
4980− }
4981− },
4982− "node_modules/which": {
4983− "version": "2.0.2",
4984− "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
4985− "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
4986− "dev": true,
4987− "dependencies": {
4988− "isexe": "^2.0.0"
4989− },
4990− "bin": {
4991− "node-which": "bin/node-which"
4992− },
4993− "engines": {
4994− "node": ">= 8"
4995− }
4996− },
4997− "node_modules/wrap-ansi": {
4998− "version": "7.0.0",
4999− "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
5000− "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
5001− "dev": true,
5002− "dependencies": {
5003− "ansi-styles": "^4.0.0",
5004− "string-width": "^4.1.0",
5005− "strip-ansi": "^6.0.0"
5006− },
5007− "engines": {
5008− "node": ">=10"
5009− },
5010− "funding": {
5011− "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
5012− }
5013− },
5014− "node_modules/wrappy": {
5015− "version": "1.0.2",
5016− "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
5017− "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
5018− "dev": true
5019− },
5020− "node_modules/xml-lexer": {
5021− "version": "0.2.2",
5022− "resolved": "https://registry.npmjs.org/xml-lexer/-/xml-lexer-0.2.2.tgz",
5023− "integrity": "sha1-UYGTpKozTVj8fSSLVJB5uJkH4EY=",
5024− "dependencies": {
5025− "eventemitter3": "^2.0.0"
5026− }
5027− },
5028− "node_modules/xml-reader": {
5029− "version": "2.4.3",
5030− "resolved": "https://registry.npmjs.org/xml-reader/-/xml-reader-2.4.3.tgz",
5031− "integrity": "sha1-n4EMr3xCWlqvuEixxFEDyecddTA=",
5032− "dependencies": {
5033− "eventemitter3": "^2.0.0",
5034− "xml-lexer": "^0.2.2"
5035− }
5036− },
5037− "node_modules/xtend": {
5038− "version": "4.0.2",
5039− "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
5040− "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
5041− "dev": true,
5042− "engines": {
5043− "node": ">=0.4"
5044− }
5045− },
5046− "node_modules/y18n": {
5047− "version": "5.0.8",
5048− "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
5049− "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
5050− "dev": true,
5051− "engines": {
5052− "node": ">=10"
5053− }
5054− },
5055− "node_modules/yaml": {
5056− "version": "1.10.2",
5057− "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
5058− "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
5059− "dev": true,
5060− "engines": {
5061− "node": ">= 6"
5062− }
5063− },
5064− "node_modules/yargs": {
5065− "version": "16.2.0",
5066− "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
5067− "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
5068− "dev": true,
5069− "dependencies": {
5070− "cliui": "^7.0.2",
5071− "escalade": "^3.1.1",
5072− "get-caller-file": "^2.0.5",
5073− "require-directory": "^2.1.1",
5074− "string-width": "^4.2.0",
5075− "y18n": "^5.0.5",
5076− "yargs-parser": "^20.2.2"
5077− },
5078− "engines": {
5079− "node": ">=10"
5080− }
5081− },
5082− "node_modules/yargs-parser": {
5083− "version": "20.2.9",
5084− "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
5085− "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
5086− "dev": true,
5087− "engines": {
5088− "node": ">=10"
5089− }
5090− }
5091− },
5092− "dependencies": {
5093− "@babel/code-frame": {
5094− "version": "7.16.7",
5095− "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
5096− "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
5097− "dev": true,
5098− "requires": {
5099− "@babel/highlight": "^7.16.7"
5100− }
5101− },
5102− "@babel/helper-validator-identifier": {
5103− "version": "7.16.7",
5104− "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
5105− "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==",
5106− "dev": true
5107− },
5108− "@babel/highlight": {
5109− "version": "7.16.7",
5110− "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz",
5111− "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==",
5112− "dev": true,
5113− "requires": {
5114− "@babel/helper-validator-identifier": "^7.16.7",
5115− "chalk": "^2.0.0",
5116− "js-tokens": "^4.0.0"
5117− },
5118− "dependencies": {
5119− "ansi-styles": {
5120− "version": "3.2.1",
5121− "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
5122− "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
5123− "dev": true,
5124− "requires": {
5125− "color-convert": "^1.9.0"
5126− }
5127− },
5128− "chalk": {
5129− "version": "2.4.2",
5130− "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
5131− "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
5132− "dev": true,
5133− "requires": {
5134− "ansi-styles": "^3.2.1",
5135− "escape-string-regexp": "^1.0.5",
5136− "supports-color": "^5.3.0"
5137− }
5138− },
5139− "color-convert": {
5140− "version": "1.9.3",
5141− "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
5142− "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
5143− "dev": true,
5144− "requires": {
5145− "color-name": "1.1.3"
5146− }
5147− },
5148− "color-name": {
5149− "version": "1.1.3",
5150− "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
5151− "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
5152− "dev": true
5153− },
5154− "has-flag": {
5155− "version": "3.0.0",
5156− "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
5157− "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
5158− "dev": true
5159− },
5160− "supports-color": {
5161− "version": "5.5.0",
5162− "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
5163− "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
5164− "dev": true,
5165− "requires": {
5166− "has-flag": "^3.0.0"
5167− }
5168− }
5169− }
5170− },
5171− "@babel/runtime": {
5172− "version": "7.16.7",
5173− "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz",
5174− "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==",
5175− "requires": {
5176− "regenerator-runtime": "^0.13.4"
5177− }
5178− },
5179− "@microsoft/fetch-event-source": {
5180− "version": "2.0.1",
5181− "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz",
5182− "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA=="
5183− },
5184− "@nodelib/fs.scandir": {
5185− "version": "2.1.5",
5186− "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
5187− "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
5188− "dev": true,
5189− "requires": {
5190− "@nodelib/fs.stat": "2.0.5",
5191− "run-parallel": "^1.1.9"
5192− }
5193− },
5194− "@nodelib/fs.stat": {
5195− "version": "2.0.5",
5196− "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
5197− "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
5198− "dev": true
5199− },
5200− "@nodelib/fs.walk": {
5201− "version": "1.2.8",
5202− "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
5203− "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
5204− "dev": true,
5205− "requires": {
5206− "@nodelib/fs.scandir": "2.1.5",
5207− "fastq": "^1.6.0"
5208− }
5209− },
5210− "@popperjs/core": {
5211− "version": "2.11.5",
5212− "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz",
5213− "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw=="
5214− },
5215− "@rollup/pluginutils": {
5216− "version": "4.1.2",
5217− "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.1.2.tgz",
5218− "integrity": "sha512-ROn4qvkxP9SyPeHaf7uQC/GPFY6L/OWy9+bd9AwcjOAWQwxRscoEyAUD8qCY5o5iL4jqQwoLk2kaTKJPb/HwzQ==",
5219− "dev": true,
5220− "requires": {
5221− "estree-walker": "^2.0.1",
5222− "picomatch": "^2.2.2"
5223− }
5224− },
5225− "@sveltejs/vite-plugin-svelte": {
5226− "version": "1.0.0-next.34",
5227− "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.34.tgz",
5228− "integrity": "sha512-qZH2jndijrdkvevgbO7OH3iQsviM5Kz7h5APiNP4yEMZTrwq9bifzYvco6BprwtPvLb5wYlRVFZUOdusY6AovQ==",
5229− "dev": true,
5230− "requires": {
5231− "@rollup/pluginutils": "^4.1.2",
5232− "debug": "^4.3.3",
5233− "kleur": "^4.1.4",
5234− "magic-string": "^0.25.7",
5235− "require-relative": "^0.8.7",
5236− "svelte-hmr": "^0.14.9"
5237− }
5238− },
5239− "@tlon/phonemes-js": {
5240− "version": "1.0.0",
5241− "resolved": "https://registry.npmjs.org/@tlon/phonemes-js/-/phonemes-js-1.0.0.tgz",
5242− "integrity": "sha512-o8zLHidOYkn5So6BSKduueoJBKBK97Q9Puwo/9Orae1DDhEGE8HqYvbGNaT6VuIMiuK8WoB/FAx5hHUrnQ5GxQ=="
5243− },
5244− "@tlon/sigil-js": {
5245− "version": "1.4.5",
5246− "resolved": "https://registry.npmjs.org/@tlon/sigil-js/-/sigil-js-1.4.5.tgz",
5247− "integrity": "sha512-+Fn0EizPetjePaK+z8njjzE74wxzqIRLVM8W53Dlri6XU87wJ4vk82baVGgZQFAQs96rYM/f4WV7kCzuSxSMAw==",
4137+ "invariant": {
4138+ "version": "2.2.4",
4139+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
4140+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
52484141 "requires": {
5249− "invariant": "^2.2.4",
5250− "svgson": "^4.0.0",
5251− "transformation-matrix": "2.1.1"
5252− }
5253− },
5254− "@tsconfig/svelte": {
5255− "version": "2.0.1",
5256− "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-2.0.1.tgz",
5257− "integrity": "sha512-aqkICXbM1oX5FfgZd2qSSAGdyo/NRxjWCamxoyi3T8iVQnzGge19HhDYzZ6NrVOW7bhcWNSq9XexWFtMzbB24A==",
5258− "dev": true
5259− },
5260− "@types/node": {
5261− "version": "17.0.8",
5262− "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.8.tgz",
5263− "integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==",
5264− "dev": true
5265− },
5266− "@types/parse-json": {
5267− "version": "4.0.0",
5268− "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
5269− "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
5270− "dev": true
5271− },
5272− "@types/pug": {
5273− "version": "2.0.6",
5274− "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz",
5275− "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==",
5276− "dev": true
5277− },
5278− "@types/sass": {
5279− "version": "1.43.1",
5280− "resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.43.1.tgz",
5281− "integrity": "sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==",
5282− "dev": true,
5283− "requires": {
5284− "@types/node": "*"
5285− }
5286− },
5287− "@urbit/api": {
5288− "version": "2.1.0",
5289− "resolved": "https://registry.npmjs.org/@urbit/api/-/api-2.1.0.tgz",
5290− "integrity": "sha512-2njwpvZ2s23gp5C4v9uDynU1wxrN33+vloqpvlErUhMR/4R6mXE4cMvsZzj/fCGOa0J3LRV/If7XmgG+kY69Tg==",
5291− "requires": {
5292− "@babel/runtime": "^7.16.0",
5293− "big-integer": "^1.6.48",
5294− "core-js": "^3.19.1",
5295− "immer": "^9.0.1",
5296− "urbit-ob": "^5.0.1"
5297− }
5298− },
5299− "@urbit/http-api": {
5300− "version": "2.1.0",
5301− "resolved": "https://registry.npmjs.org/@urbit/http-api/-/http-api-2.1.0.tgz",
5302− "integrity": "sha512-eXYar3ofw1HlhHy2NSkJPCo//oZzfnrGXIJAKQ/gWSzd8x3o7eiiIQjoFbuWojaACy8T9fXsGzpxEqoXZlWDhw==",
5303− "requires": {
5304− "@babel/runtime": "^7.12.5",
5305− "@microsoft/fetch-event-source": "^2.0.0",
5306− "browser-or-node": "^1.3.0",
5307− "core-js": "^3.19.1"
5308− }
5309− },
5310− "@urbit/vite-plugin-urbit": {
5311− "version": "0.8.0",
5312− "resolved": "https://registry.npmjs.org/@urbit/vite-plugin-urbit/-/vite-plugin-urbit-0.8.0.tgz",
5313− "integrity": "sha512-cx540xZBuHfzud/kOuYU4xPpsFcgE7mF0heac5uXVutDqjySvVXimEuZgBN23ULC7l60R/bAJ2jOWygBwWen4A==",
5314− "dev": true,
5315− "requires": {
5316− "vite-plugin-html-config": "^1.0.6",
5317− "vite-plugin-rewrite-all": "^0.1.2"
5318− }
5319− },
5320− "acorn": {
5321− "version": "7.4.1",
5322− "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
5323− "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
5324− "dev": true
5325− },
5326− "acorn-node": {
5327− "version": "1.8.2",
5328− "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
5329− "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
5330− "dev": true,
5331− "requires": {
5332− "acorn": "^7.0.0",
5333− "acorn-walk": "^7.0.0",
5334− "xtend": "^4.0.2"
5335− }
5336− },
5337− "acorn-walk": {
5338− "version": "7.2.0",
5339− "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
5340− "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
5341− "dev": true
5342− },
5343− "ansi-regex": {
5344− "version": "5.0.1",
5345− "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
5346− "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
5347− "dev": true
5348− },
5349− "ansi-styles": {
5350− "version": "4.3.0",
5351− "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
5352− "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
5353− "dev": true,
5354− "requires": {
5355− "color-convert": "^2.0.1"
5356− }
5357− },
5358− "anymatch": {
5359− "version": "3.1.2",
5360− "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
5361− "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
5362− "requires": {
5363− "normalize-path": "^3.0.0",
5364− "picomatch": "^2.0.4"
5365− }
5366− },
5367− "arg": {
5368− "version": "5.0.1",
5369− "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.1.tgz",
5370− "integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==",
5371− "dev": true
5372− },
5373− "array-union": {
5374− "version": "3.0.1",
5375− "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz",
5376− "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==",
5377− "dev": true
5378− },
5379− "autoprefixer": {
5380− "version": "10.4.2",
5381− "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz",
5382− "integrity": "sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==",
5383− "dev": true,
5384− "requires": {
5385− "browserslist": "^4.19.1",
5386− "caniuse-lite": "^1.0.30001297",
5387− "fraction.js": "^4.1.2",
5388− "normalize-range": "^0.1.2",
5389− "picocolors": "^1.0.0",
5390− "postcss-value-parser": "^4.2.0"
5391− }
5392− },
5393− "balanced-match": {
5394− "version": "1.0.2",
5395− "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
5396− "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
5397− "dev": true
5398− },
5399− "big-integer": {
5400− "version": "1.6.51",
5401− "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
5402− "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg=="
5403− },
5404− "binary-extensions": {
5405− "version": "2.2.0",
5406− "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
5407− "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
5408− },
5409− "bn.js": {
5410− "version": "5.2.0",
5411− "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
5412− "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
5413− },
5414− "brace-expansion": {
5415− "version": "1.1.11",
5416− "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
5417− "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
5418− "dev": true,
5419− "requires": {
5420− "balanced-match": "^1.0.0",
5421− "concat-map": "0.0.1"
5422− }
5423− },
5424− "braces": {
5425− "version": "3.0.2",
5426− "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
5427− "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
5428− "requires": {
5429− "fill-range": "^7.0.1"
5430− }
5431− },
5432− "browser-or-node": {
5433− "version": "1.3.0",
5434− "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-1.3.0.tgz",
5435− "integrity": "sha512-0F2z/VSnLbmEeBcUrSuDH5l0HxTXdQQzLjkmBR4cYfvg1zJrKSlmIZFqyFR8oX0NrwPhy3c3HQ6i3OxMbew4Tg=="
5436− },
5437− "browserslist": {
5438− "version": "4.19.1",
5439− "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz",
5440− "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==",
5441− "dev": true,
5442− "requires": {
5443− "caniuse-lite": "^1.0.30001286",
5444− "electron-to-chromium": "^1.4.17",
5445− "escalade": "^3.1.1",
5446− "node-releases": "^2.0.1",
5447− "picocolors": "^1.0.0"
5448− }
5449− },
5450− "buffer-crc32": {
5451− "version": "0.2.13",
5452− "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
5453− "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
5454− "dev": true
5455− },
5456− "callsites": {
5457− "version": "3.1.0",
5458− "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
5459− "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
5460− "dev": true
5461− },
5462− "camelcase-css": {
5463− "version": "2.0.1",
5464− "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
5465− "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
5466− "dev": true
5467− },
5468− "caniuse-lite": {
5469− "version": "1.0.30001297",
5470− "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001297.tgz",
5471− "integrity": "sha512-6bbIbowYG8vFs/Lk4hU9jFt7NknGDleVAciK916tp6ft1j+D//ZwwL6LbF1wXMQ32DMSjeuUV8suhh6dlmFjcA==",
5472− "dev": true
5473− },
5474− "chalk": {
5475− "version": "4.1.2",
5476− "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
5477− "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
5478− "dev": true,
5479− "requires": {
5480− "ansi-styles": "^4.1.0",
5481− "supports-color": "^7.1.0"
5482− }
5483− },
5484− "chokidar": {
5485− "version": "3.5.2",
5486− "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
5487− "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
5488− "requires": {
5489− "anymatch": "~3.1.2",
5490− "braces": "~3.0.2",
5491− "fsevents": "~2.3.2",
5492− "glob-parent": "~5.1.2",
5493− "is-binary-path": "~2.1.0",
5494− "is-glob": "~4.0.1",
5495− "normalize-path": "~3.0.0",
5496− "readdirp": "~3.6.0"
5497− }
5498− },
5499− "cliui": {
5500− "version": "7.0.4",
5501− "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
5502− "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
5503− "dev": true,
5504− "requires": {
5505− "string-width": "^4.2.0",
5506− "strip-ansi": "^6.0.0",
5507− "wrap-ansi": "^7.0.0"
5508− }
5509− },
5510− "color-convert": {
5511− "version": "2.0.1",
5512− "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
5513− "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
5514− "dev": true,
5515− "requires": {
5516− "color-name": "~1.1.4"
5517− }
5518− },
5519− "color-name": {
5520− "version": "1.1.4",
5521− "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
5522− "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
5523− "dev": true
5524− },
5525− "concat-map": {
5526− "version": "0.0.1",
5527− "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
5528− "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
5529− "dev": true
5530− },
5531− "concurrently": {
5532− "version": "7.0.0",
5533− "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.0.0.tgz",
5534− "integrity": "sha512-WKM7PUsI8wyXpF80H+zjHP32fsgsHNQfPLw/e70Z5dYkV7hF+rf8q3D+ScWJIEr57CpkO3OWBko6hwhQLPR8Pw==",
5535− "dev": true,
5536− "requires": {
5537− "chalk": "^4.1.0",
5538− "date-fns": "^2.16.1",
5539− "lodash": "^4.17.21",
5540− "rxjs": "^6.6.3",
5541− "spawn-command": "^0.0.2-1",
5542− "supports-color": "^8.1.0",
5543− "tree-kill": "^1.2.2",
5544− "yargs": "^16.2.0"
5545− },
5546− "dependencies": {
5547− "supports-color": {
5548− "version": "8.1.1",
5549− "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
5550− "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
5551− "dev": true,
5552− "requires": {
5553− "has-flag": "^4.0.0"
5554− }
5555− }
5556− }
5557− },
5558− "connect-history-api-fallback": {
5559− "version": "1.6.0",
5560− "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
5561− "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
5562− "dev": true
5563− },
5564− "core-js": {
5565− "version": "3.20.2",
5566− "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.2.tgz",
5567− "integrity": "sha512-nuqhq11DcOAbFBV4zCbKeGbKQsUDRqTX0oqx7AttUBuqe3h20ixsE039QHelbL6P4h+9kytVqyEtyZ6gsiwEYw=="
5568− },
5569− "cosmiconfig": {
5570− "version": "7.0.1",
5571− "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
5572− "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
5573− "dev": true,
5574− "requires": {
5575− "@types/parse-json": "^4.0.0",
5576− "import-fresh": "^3.2.1",
5577− "parse-json": "^5.0.0",
5578− "path-type": "^4.0.0",
5579− "yaml": "^1.10.0"
5580− }
5581− },
5582− "cross-env": {
5583− "version": "7.0.3",
5584− "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
5585− "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
5586− "dev": true,
5587− "requires": {
5588− "cross-spawn": "^7.0.1"
5589− }
5590− },
5591− "cross-spawn": {
5592− "version": "7.0.3",
5593− "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
5594− "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
5595− "dev": true,
5596− "requires": {
5597− "path-key": "^3.1.0",
5598− "shebang-command": "^2.0.0",
5599− "which": "^2.0.1"
5600− }
5601− },
5602− "cssesc": {
5603− "version": "3.0.0",
5604− "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
5605− "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
5606− "dev": true
5607− },
5608− "date-fns": {
5609− "version": "2.28.0",
5610− "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz",
5611− "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==",
5612− "dev": true
5613− },
5614− "debug": {
5615− "version": "4.3.3",
5616− "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
5617− "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
5618− "dev": true,
5619− "requires": {
5620− "ms": "2.1.2"
5621− }
5622− },
5623− "deep-rename-keys": {
5624− "version": "0.2.1",
5625− "resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz",
5626− "integrity": "sha1-7eeFN9emaivmFRfir5Vtf1ij8dg=",
5627− "requires": {
5628− "kind-of": "^3.0.2",
5629− "rename-keys": "^1.1.2"
5630− }
5631− },
5632− "defined": {
5633− "version": "1.0.0",
5634− "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
5635− "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
5636− "dev": true
5637− },
5638− "dependency-graph": {
5639− "version": "0.11.0",
5640− "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
5641− "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
5642− "dev": true
5643− },
5644− "detect-indent": {
5645− "version": "6.1.0",
5646− "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
5647− "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
5648− "dev": true
5649− },
5650− "detective": {
5651− "version": "5.2.0",
5652− "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz",
5653− "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==",
5654− "dev": true,
5655− "requires": {
5656− "acorn-node": "^1.6.1",
5657− "defined": "^1.0.0",
5658− "minimist": "^1.1.1"
5659− }
5660− },
5661− "didyoumean": {
5662− "version": "1.2.2",
5663− "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
5664− "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
5665− "dev": true
5666− },
5667− "dir-glob": {
5668− "version": "3.0.1",
5669− "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
5670− "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
5671− "dev": true,
5672− "requires": {
5673− "path-type": "^4.0.0"
5674− }
5675− },
5676− "dlv": {
5677− "version": "1.1.3",
5678− "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
5679− "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
5680− "dev": true
5681− },
5682− "electron-to-chromium": {
5683− "version": "1.4.38",
5684− "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.38.tgz",
5685− "integrity": "sha512-WhHt3sZazKj0KK/UpgsbGQnUUoFeAHVishzHFExMxagpZgjiGYSC9S0ZlbhCfSH2L2i+2A1yyqOIliTctMx7KQ==",
5686− "dev": true
5687− },
5688− "emoji-regex": {
5689− "version": "8.0.0",
5690− "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
5691− "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
5692− "dev": true
5693− },
5694− "error-ex": {
5695− "version": "1.3.2",
5696− "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
5697− "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
5698− "dev": true,
5699− "requires": {
5700− "is-arrayish": "^0.2.1"
5701− }
5702− },
5703− "es6-promise": {
5704− "version": "3.3.1",
5705− "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
5706− "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=",
5707− "dev": true
5708− },
5709− "esbuild": {
5710− "version": "0.13.15",
5711− "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.15.tgz",
5712− "integrity": "sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==",
5713− "dev": true,
5714− "requires": {
5715− "esbuild-android-arm64": "0.13.15",
5716− "esbuild-darwin-64": "0.13.15",
5717− "esbuild-darwin-arm64": "0.13.15",
5718− "esbuild-freebsd-64": "0.13.15",
5719− "esbuild-freebsd-arm64": "0.13.15",
5720− "esbuild-linux-32": "0.13.15",
5721− "esbuild-linux-64": "0.13.15",
5722− "esbuild-linux-arm": "0.13.15",
5723− "esbuild-linux-arm64": "0.13.15",
5724− "esbuild-linux-mips64le": "0.13.15",
5725− "esbuild-linux-ppc64le": "0.13.15",
5726− "esbuild-netbsd-64": "0.13.15",
5727− "esbuild-openbsd-64": "0.13.15",
5728− "esbuild-sunos-64": "0.13.15",
5729− "esbuild-windows-32": "0.13.15",
5730− "esbuild-windows-64": "0.13.15",
5731− "esbuild-windows-arm64": "0.13.15"
5732− }
5733− },
5734− "esbuild-android-arm64": {
5735− "version": "0.13.15",
5736− "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz",
5737− "integrity": "sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg==",
5738− "dev": true,
5739− "optional": true
5740− },
5741− "esbuild-darwin-64": {
5742− "version": "0.13.15",
5743− "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz",
5744− "integrity": "sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==",
5745− "dev": true,
5746− "optional": true
5747− },
5748− "esbuild-darwin-arm64": {
5749− "version": "0.13.15",
5750− "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz",
5751− "integrity": "sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==",
5752− "dev": true,
5753− "optional": true
5754− },
5755− "esbuild-freebsd-64": {
5756− "version": "0.13.15",
5757− "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz",
5758− "integrity": "sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==",
5759− "dev": true,
5760− "optional": true
5761− },
5762− "esbuild-freebsd-arm64": {
5763− "version": "0.13.15",
5764− "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz",
5765− "integrity": "sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==",
5766− "dev": true,
5767− "optional": true
5768− },
5769− "esbuild-linux-32": {
5770− "version": "0.13.15",
5771− "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz",
5772− "integrity": "sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==",
5773− "dev": true,
5774− "optional": true
5775− },
5776− "esbuild-linux-64": {
5777− "version": "0.13.15",
5778− "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz",
5779− "integrity": "sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==",
5780− "dev": true,
5781− "optional": true
5782− },
5783− "esbuild-linux-arm": {
5784− "version": "0.13.15",
5785− "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz",
5786− "integrity": "sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==",
5787− "dev": true,
5788− "optional": true
5789− },
5790− "esbuild-linux-arm64": {
5791− "version": "0.13.15",
5792− "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz",
5793− "integrity": "sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==",
5794− "dev": true,
5795− "optional": true
5796− },
5797− "esbuild-linux-mips64le": {
5798− "version": "0.13.15",
5799− "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz",
5800− "integrity": "sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==",
5801− "dev": true,
5802− "optional": true
5803− },
5804− "esbuild-linux-ppc64le": {
5805− "version": "0.13.15",
5806− "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz",
5807− "integrity": "sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==",
5808− "dev": true,
5809− "optional": true
5810− },
5811− "esbuild-netbsd-64": {
5812− "version": "0.13.15",
5813− "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz",
5814− "integrity": "sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==",
5815− "dev": true,
5816− "optional": true
5817− },
5818− "esbuild-openbsd-64": {
5819− "version": "0.13.15",
5820− "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz",
5821− "integrity": "sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==",
5822− "dev": true,
5823− "optional": true
5824− },
5825− "esbuild-sunos-64": {
5826− "version": "0.13.15",
5827− "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz",
5828− "integrity": "sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==",
5829− "dev": true,
5830− "optional": true
5831− },
5832− "esbuild-windows-32": {
5833− "version": "0.13.15",
5834− "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz",
5835− "integrity": "sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==",
5836− "dev": true,
5837− "optional": true
5838− },
5839− "esbuild-windows-64": {
5840− "version": "0.13.15",
5841− "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz",
5842− "integrity": "sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==",
5843− "dev": true,
5844− "optional": true
5845− },
5846− "esbuild-windows-arm64": {
5847− "version": "0.13.15",
5848− "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz",
5849− "integrity": "sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==",
5850− "dev": true,
5851− "optional": true
5852− },
5853− "escalade": {
5854− "version": "3.1.1",
5855− "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
5856− "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
5857− "dev": true
5858− },
5859− "escape-string-regexp": {
5860− "version": "1.0.5",
5861− "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
5862− "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
5863− "dev": true
5864− },
5865− "estree-walker": {
5866− "version": "2.0.2",
5867− "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
5868− "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
5869− "dev": true
5870− },
5871− "eventemitter3": {
5872− "version": "2.0.3",
5873− "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
5874− "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
5875− },
5876− "fast-glob": {
5877− "version": "3.2.9",
5878− "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.9.tgz",
5879− "integrity": "sha512-MBwILhhD92sziIrMQwpqcuGERF+BH99ei2a3XsGJuqEKcSycAL+w0HWokFenZXona+kjFr82Lf71eTxNRC06XQ==",
5880− "dev": true,
5881− "requires": {
5882− "@nodelib/fs.stat": "^2.0.2",
5883− "@nodelib/fs.walk": "^1.2.3",
5884− "glob-parent": "^5.1.2",
5885− "merge2": "^1.3.0",
5886− "micromatch": "^4.0.4"
5887− }
5888− },
5889− "fastq": {
5890− "version": "1.13.0",
5891− "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
5892− "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
5893− "dev": true,
5894− "requires": {
5895− "reusify": "^1.0.4"
5896− }
5897− },
5898− "fill-range": {
5899− "version": "7.0.1",
5900− "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
5901− "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
5902− "requires": {
5903− "to-regex-range": "^5.0.1"
5904− }
5905− },
5906− "fraction.js": {
5907− "version": "4.1.2",
5908− "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz",
5909− "integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==",
5910− "dev": true
5911− },
5912− "fs-extra": {
5913− "version": "10.0.0",
5914− "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
5915− "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
5916− "dev": true,
5917− "requires": {
5918− "graceful-fs": "^4.2.0",
5919− "jsonfile": "^6.0.1",
5920− "universalify": "^2.0.0"
5921− }
5922− },
5923− "fs.realpath": {
5924− "version": "1.0.0",
5925− "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
5926− "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
5927− "dev": true
5928− },
5929− "fsevents": {
5930− "version": "2.3.2",
5931− "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
5932− "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
5933− "optional": true
5934− },
5935− "function-bind": {
5936− "version": "1.1.1",
5937− "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
5938− "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
5939− "dev": true
5940− },
5941− "get-caller-file": {
5942− "version": "2.0.5",
5943− "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
5944− "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
5945− "dev": true
5946− },
5947− "get-stdin": {
5948− "version": "9.0.0",
5949− "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
5950− "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
5951− "dev": true
5952− },
5953− "get-value": {
5954− "version": "2.0.6",
5955− "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
5956− "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
5957− },
5958− "glob": {
5959− "version": "7.2.0",
5960− "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
5961− "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
5962− "dev": true,
5963− "requires": {
5964− "fs.realpath": "^1.0.0",
5965− "inflight": "^1.0.4",
5966− "inherits": "2",
5967− "minimatch": "^3.0.4",
5968− "once": "^1.3.0",
5969− "path-is-absolute": "^1.0.0"
5970− }
5971− },
5972− "glob-parent": {
5973− "version": "5.1.2",
5974− "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
5975− "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
5976− "requires": {
5977− "is-glob": "^4.0.1"
5978− }
5979− },
5980− "globby": {
5981− "version": "12.0.2",
5982− "resolved": "https://registry.npmjs.org/globby/-/globby-12.0.2.tgz",
5983− "integrity": "sha512-lAsmb/5Lww4r7MM9nCCliDZVIKbZTavrsunAsHLr9oHthrZP1qi7/gAnHOsUs9bLvEt2vKVJhHmxuL7QbDuPdQ==",
5984− "dev": true,
5985− "requires": {
5986− "array-union": "^3.0.1",
5987− "dir-glob": "^3.0.1",
5988− "fast-glob": "^3.2.7",
5989− "ignore": "^5.1.8",
5990− "merge2": "^1.4.1",
5991− "slash": "^4.0.0"
5992− }
5993− },
5994− "graceful-fs": {
5995− "version": "4.2.9",
5996− "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
5997− "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
5998− "dev": true
5999− },
6000− "has": {
6001− "version": "1.0.3",
6002− "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
6003− "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
6004− "dev": true,
6005− "requires": {
6006− "function-bind": "^1.1.1"
6007− }
6008− },
6009− "has-flag": {
6010− "version": "4.0.0",
6011− "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
6012− "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
6013− "dev": true
6014− },
6015− "has-value": {
6016− "version": "0.3.1",
6017− "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
6018− "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
6019− "requires": {
6020− "get-value": "^2.0.3",
6021− "has-values": "^0.1.4",
6022− "isobject": "^2.0.0"
6023− },
6024− "dependencies": {
6025− "isobject": {
6026− "version": "2.1.0",
6027− "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
6028− "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
6029− "requires": {
6030− "isarray": "1.0.0"
6031− }
6032− }
6033− }
6034− },
6035− "has-values": {
6036− "version": "0.1.4",
6037− "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
6038− "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
6039− },
6040− "i": {
6041− "version": "0.3.7",
6042− "resolved": "https://registry.npmjs.org/i/-/i-0.3.7.tgz",
6043− "integrity": "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q=="
6044− },
6045− "ignore": {
6046− "version": "5.2.0",
6047− "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
6048− "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
6049− "dev": true
6050− },
6051− "immer": {
6052− "version": "9.0.7",
6053− "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.7.tgz",
6054− "integrity": "sha512-KGllzpbamZDvOIxnmJ0jI840g7Oikx58lBPWV0hUh7dtAyZpFqqrBZdKka5GlTwMTZ1Tjc/bKKW4VSFAt6BqMA=="
6055− },
6056− "immutable": {
6057− "version": "4.0.0",
6058− "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
6059− "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw=="
6060− },
6061− "import-fresh": {
6062− "version": "3.3.0",
6063− "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
6064− "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
6065− "dev": true,
6066− "requires": {
6067− "parent-module": "^1.0.0",
6068− "resolve-from": "^4.0.0"
6069− }
6070− },
6071− "inflight": {
6072− "version": "1.0.6",
6073− "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
6074− "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
6075− "dev": true,
6076− "requires": {
6077− "once": "^1.3.0",
6078− "wrappy": "1"
6079− }
6080− },
6081− "inherits": {
6082− "version": "2.0.4",
6083− "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
6084− "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
6085− "dev": true
6086− },
6087− "invariant": {
6088− "version": "2.2.4",
6089− "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
6090− "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
6091− "requires": {
6092− "loose-envify": "^1.0.0"
6093− }
6094− },
6095− "is-arrayish": {
6096− "version": "0.2.1",
6097− "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
6098− "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
6099− "dev": true
6100− },
6101− "is-binary-path": {
6102− "version": "2.1.0",
6103− "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
6104− "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
6105− "requires": {
6106− "binary-extensions": "^2.0.0"
6107− }
6108− },
6109− "is-buffer": {
6110− "version": "1.1.6",
6111− "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
6112− "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
6113− },
6114− "is-core-module": {
6115− "version": "2.8.1",
6116− "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
6117− "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
6118− "dev": true,
6119− "requires": {
6120− "has": "^1.0.3"
6121− }
6122− },
6123− "is-extglob": {
6124− "version": "2.1.1",
6125− "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
6126− "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
6127− },
6128− "is-fullwidth-code-point": {
6129− "version": "3.0.0",
6130− "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
6131− "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
6132− "dev": true
6133− },
6134− "is-glob": {
6135− "version": "4.0.3",
6136− "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
6137− "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
6138− "requires": {
6139− "is-extglob": "^2.1.1"
6140− }
6141− },
6142− "is-number": {
6143− "version": "7.0.0",
6144− "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
6145− "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
6146− },
6147− "is-plain-object": {
6148− "version": "2.0.4",
6149− "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
6150− "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
6151− "requires": {
6152− "isobject": "^3.0.1"
6153− }
6154− },
6155− "isarray": {
6156− "version": "1.0.0",
6157− "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
6158− "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
6159− },
6160− "isexe": {
6161− "version": "2.0.0",
6162− "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
6163− "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
6164− "dev": true
6165− },
6166− "isobject": {
6167− "version": "3.0.1",
6168− "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
6169− "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
6170− },
6171− "js-tokens": {
6172− "version": "4.0.0",
6173− "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
6174− "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
6175− },
6176− "json-parse-even-better-errors": {
6177− "version": "2.3.1",
6178− "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
6179− "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
6180− "dev": true
6181− },
6182− "jsonfile": {
6183− "version": "6.1.0",
6184− "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
6185− "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
6186− "dev": true,
6187− "requires": {
6188− "graceful-fs": "^4.1.6",
6189− "universalify": "^2.0.0"
6190− }
6191− },
6192− "kind-of": {
6193− "version": "3.2.2",
6194− "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
6195− "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
6196− "requires": {
6197− "is-buffer": "^1.1.5"
6198− }
6199− },
6200− "kleur": {
6201− "version": "4.1.4",
6202− "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
6203− "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==",
6204− "dev": true
6205− },
6206− "lilconfig": {
6207− "version": "2.0.4",
6208− "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz",
6209− "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==",
6210− "dev": true
6211− },
6212− "lines-and-columns": {
6213− "version": "1.2.4",
6214− "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
6215− "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
6216− "dev": true
6217− },
6218− "lodash": {
6219− "version": "4.17.21",
6220− "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
6221− "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
6222− "dev": true
6223− },
6224− "lodash.chunk": {
6225− "version": "4.2.0",
6226− "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz",
6227− "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw="
6228− },
6229− "lodash.isequal": {
6230− "version": "4.5.0",
6231− "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
6232− "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
6233− },
6234− "loose-envify": {
6235− "version": "1.4.0",
6236− "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
6237− "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
6238− "requires": {
6239− "js-tokens": "^3.0.0 || ^4.0.0"
6240− }
6241− },
6242− "magic-string": {
6243− "version": "0.25.7",
6244− "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
6245− "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
6246− "dev": true,
6247− "requires": {
6248− "sourcemap-codec": "^1.4.4"
6249− }
6250− },
6251− "merge2": {
6252− "version": "1.4.1",
6253− "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
6254− "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
6255− "dev": true
6256− },
6257− "micromatch": {
6258− "version": "4.0.4",
6259− "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
6260− "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
6261− "dev": true,
6262− "requires": {
6263− "braces": "^3.0.1",
6264− "picomatch": "^2.2.3"
6265− }
6266− },
6267− "min-indent": {
6268− "version": "1.0.1",
6269− "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
6270− "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
6271− "dev": true
6272− },
6273− "minimatch": {
6274− "version": "3.0.4",
6275− "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
6276− "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
6277− "dev": true,
6278− "requires": {
6279− "brace-expansion": "^1.1.7"
6280− }
6281− },
6282− "minimist": {
6283− "version": "1.2.6",
6284− "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
6285− "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
6286− "dev": true
6287− },
6288− "mkdirp": {
6289− "version": "0.5.5",
6290− "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
6291− "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
6292− "dev": true,
6293− "requires": {
6294− "minimist": "^1.2.5"
6295− }
6296− },
6297− "mri": {
6298− "version": "1.2.0",
6299− "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
6300− "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
6301− "dev": true
6302− },
6303− "ms": {
6304− "version": "2.1.2",
6305− "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
6306− "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
6307− "dev": true
6308− },
6309− "nanoid": {
6310− "version": "3.3.1",
6311− "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
6312− "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
6313− "dev": true
6314− },
6315− "node-releases": {
6316− "version": "2.0.1",
6317− "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz",
6318− "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==",
6319− "dev": true
6320− },
6321− "normalize-path": {
6322− "version": "3.0.0",
6323− "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
6324− "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
6325− },
6326− "normalize-range": {
6327− "version": "0.1.2",
6328− "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
6329− "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
6330− "dev": true
6331− },
6332− "npm": {
6333− "version": "8.6.0",
6334− "resolved": "https://registry.npmjs.org/npm/-/npm-8.6.0.tgz",
6335− "integrity": "sha512-icekvN8FJFESIFkLaFEVl05Nocl5Id5HnoVhJzhCUvtNY8tj9kfUlH/J527fZq/8ltsAUqpettfutwRjQYS2fA==",
6336− "requires": {
6337− "@isaacs/string-locale-compare": "^1.1.0",
6338− "@npmcli/arborist": "^5.0.4",
6339− "@npmcli/ci-detect": "^2.0.0",
6340− "@npmcli/config": "^4.0.1",
6341− "@npmcli/fs": "^2.1.0",
6342− "@npmcli/map-workspaces": "^2.0.2",
6343− "@npmcli/package-json": "^1.0.1",
6344− "@npmcli/run-script": "^3.0.1",
6345− "abbrev": "~1.1.1",
6346− "ansicolors": "~0.3.2",
6347− "ansistyles": "~0.1.3",
6348− "archy": "~1.0.0",
6349− "cacache": "^16.0.3",
6350− "chalk": "^4.1.2",
6351− "chownr": "^2.0.0",
6352− "cli-columns": "^4.0.0",
6353− "cli-table3": "^0.6.1",
6354− "columnify": "^1.6.0",
6355− "fastest-levenshtein": "^1.0.12",
6356− "glob": "^7.2.0",
6357− "graceful-fs": "^4.2.9",
6358− "hosted-git-info": "^5.0.0",
6359− "ini": "^2.0.0",
6360− "init-package-json": "^3.0.2",
6361− "is-cidr": "^4.0.2",
6362− "json-parse-even-better-errors": "^2.3.1",
6363− "libnpmaccess": "^6.0.2",
6364− "libnpmdiff": "^4.0.2",
6365− "libnpmexec": "^4.0.2",
6366− "libnpmfund": "^3.0.1",
6367− "libnpmhook": "^8.0.2",
6368− "libnpmorg": "^4.0.2",
6369− "libnpmpack": "^4.0.2",
6370− "libnpmpublish": "^6.0.2",
6371− "libnpmsearch": "^5.0.2",
6372− "libnpmteam": "^4.0.2",
6373− "libnpmversion": "^3.0.1",
6374− "make-fetch-happen": "^10.1.1",
6375− "minipass": "^3.1.6",
6376− "minipass-pipeline": "^1.2.4",
6377− "mkdirp": "^1.0.4",
6378− "mkdirp-infer-owner": "^2.0.0",
6379− "ms": "^2.1.2",
6380− "node-gyp": "^9.0.0",
6381− "nopt": "^5.0.0",
6382− "npm-audit-report": "^3.0.0",
6383− "npm-install-checks": "^4.0.0",
6384− "npm-package-arg": "^9.0.1",
6385− "npm-pick-manifest": "^7.0.0",
6386− "npm-profile": "^6.0.2",
6387− "npm-registry-fetch": "^13.1.0",
6388− "npm-user-validate": "^1.0.1",
6389− "npmlog": "^6.0.1",
6390− "opener": "^1.5.2",
6391− "pacote": "^13.0.5",
6392− "parse-conflict-json": "^2.0.2",
6393− "proc-log": "^2.0.1",
6394− "qrcode-terminal": "^0.12.0",
6395− "read": "~1.0.7",
6396− "read-package-json": "^5.0.0",
6397− "read-package-json-fast": "^2.0.3",
6398− "readdir-scoped-modules": "^1.1.0",
6399− "rimraf": "^3.0.2",
6400− "semver": "^7.3.5",
6401− "ssri": "^8.0.1",
6402− "tar": "^6.1.11",
6403− "text-table": "~0.2.0",
6404− "tiny-relative-date": "^1.3.0",
6405− "treeverse": "^1.0.4",
6406− "validate-npm-package-name": "^4.0.0",
6407− "which": "^2.0.2",
6408− "write-file-atomic": "^4.0.1"
6409− },
6410− "dependencies": {
6411− "@gar/promisify": {
6412− "version": "1.1.3",
6413− "bundled": true
6414− },
6415− "@isaacs/string-locale-compare": {
6416− "version": "1.1.0",
6417− "bundled": true
6418− },
6419− "@npmcli/arborist": {
6420− "version": "5.0.4",
6421− "bundled": true,
6422− "requires": {
6423− "@isaacs/string-locale-compare": "^1.1.0",
6424− "@npmcli/installed-package-contents": "^1.0.7",
6425− "@npmcli/map-workspaces": "^2.0.0",
6426− "@npmcli/metavuln-calculator": "^3.0.1",
6427− "@npmcli/move-file": "^1.1.0",
6428− "@npmcli/name-from-folder": "^1.0.1",
6429− "@npmcli/node-gyp": "^1.0.3",
6430− "@npmcli/package-json": "^1.0.1",
6431− "@npmcli/run-script": "^3.0.0",
6432− "bin-links": "^3.0.0",
6433− "cacache": "^16.0.0",
6434− "common-ancestor-path": "^1.0.1",
6435− "json-parse-even-better-errors": "^2.3.1",
6436− "json-stringify-nice": "^1.1.4",
6437− "mkdirp": "^1.0.4",
6438− "mkdirp-infer-owner": "^2.0.0",
6439− "nopt": "^5.0.0",
6440− "npm-install-checks": "^4.0.0",
6441− "npm-package-arg": "^9.0.0",
6442− "npm-pick-manifest": "^7.0.0",
6443− "npm-registry-fetch": "^13.0.0",
6444− "npmlog": "^6.0.1",
6445− "pacote": "^13.0.5",
6446− "parse-conflict-json": "^2.0.1",
6447− "proc-log": "^2.0.0",
6448− "promise-all-reject-late": "^1.0.0",
6449− "promise-call-limit": "^1.0.1",
6450− "read-package-json-fast": "^2.0.2",
6451− "readdir-scoped-modules": "^1.1.0",
6452− "rimraf": "^3.0.2",
6453− "semver": "^7.3.5",
6454− "ssri": "^8.0.1",
6455− "treeverse": "^1.0.4",
6456− "walk-up-path": "^1.0.0"
6457− }
6458− },
6459− "@npmcli/ci-detect": {
6460− "version": "2.0.0",
6461− "bundled": true
6462− },
6463− "@npmcli/config": {
6464− "version": "4.0.1",
6465− "bundled": true,
6466− "requires": {
6467− "@npmcli/map-workspaces": "^2.0.1",
6468− "ini": "^2.0.0",
6469− "mkdirp-infer-owner": "^2.0.0",
6470− "nopt": "^5.0.0",
6471− "proc-log": "^2.0.0",
6472− "read-package-json-fast": "^2.0.3",
6473− "semver": "^7.3.5",
6474− "walk-up-path": "^1.0.0"
6475− }
6476− },
6477− "@npmcli/disparity-colors": {
6478− "version": "1.0.1",
6479− "bundled": true,
6480− "requires": {
6481− "ansi-styles": "^4.3.0"
6482− }
6483− },
6484− "@npmcli/fs": {
6485− "version": "2.1.0",
6486− "bundled": true,
6487− "requires": {
6488− "@gar/promisify": "^1.1.3",
6489− "semver": "^7.3.5"
6490− }
6491− },
6492− "@npmcli/git": {
6493− "version": "3.0.0",
6494− "bundled": true,
6495− "requires": {
6496− "@npmcli/promise-spawn": "^1.3.2",
6497− "lru-cache": "^7.3.1",
6498− "mkdirp": "^1.0.4",
6499− "npm-pick-manifest": "^7.0.0",
6500− "proc-log": "^2.0.0",
6501− "promise-inflight": "^1.0.1",
6502− "promise-retry": "^2.0.1",
6503− "semver": "^7.3.5",
6504− "which": "^2.0.2"
6505− }
6506− },
6507− "@npmcli/installed-package-contents": {
6508− "version": "1.0.7",
6509− "bundled": true,
6510− "requires": {
6511− "npm-bundled": "^1.1.1",
6512− "npm-normalize-package-bin": "^1.0.1"
6513− }
6514− },
6515− "@npmcli/map-workspaces": {
6516− "version": "2.0.2",
6517− "bundled": true,
6518− "requires": {
6519− "@npmcli/name-from-folder": "^1.0.1",
6520− "glob": "^7.2.0",
6521− "minimatch": "^5.0.1",
6522− "read-package-json-fast": "^2.0.3"
6523− },
6524− "dependencies": {
6525− "brace-expansion": {
6526− "version": "2.0.1",
6527− "bundled": true,
6528− "requires": {
6529− "balanced-match": "^1.0.0"
6530− }
6531− },
6532− "minimatch": {
6533− "version": "5.0.1",
6534− "bundled": true,
6535− "requires": {
6536− "brace-expansion": "^2.0.1"
6537− }
6538− }
6539− }
6540− },
6541− "@npmcli/metavuln-calculator": {
6542− "version": "3.0.1",
6543− "bundled": true,
6544− "requires": {
6545− "cacache": "^16.0.0",
6546− "json-parse-even-better-errors": "^2.3.1",
6547− "pacote": "^13.0.3",
6548− "semver": "^7.3.5"
6549− }
6550− },
6551− "@npmcli/move-file": {
6552− "version": "1.1.2",
6553− "bundled": true,
6554− "requires": {
6555− "mkdirp": "^1.0.4",
6556− "rimraf": "^3.0.2"
6557− }
6558− },
6559− "@npmcli/name-from-folder": {
6560− "version": "1.0.1",
6561− "bundled": true
6562− },
6563− "@npmcli/node-gyp": {
6564− "version": "1.0.3",
6565− "bundled": true
6566− },
6567− "@npmcli/package-json": {
6568− "version": "1.0.1",
6569− "bundled": true,
6570− "requires": {
6571− "json-parse-even-better-errors": "^2.3.1"
6572− }
6573− },
6574− "@npmcli/promise-spawn": {
6575− "version": "1.3.2",
6576− "bundled": true,
6577− "requires": {
6578− "infer-owner": "^1.0.4"
6579− }
6580− },
6581− "@npmcli/run-script": {
6582− "version": "3.0.1",
6583− "bundled": true,
6584− "requires": {
6585− "@npmcli/node-gyp": "^1.0.3",
6586− "@npmcli/promise-spawn": "^1.3.2",
6587− "node-gyp": "^9.0.0",
6588− "read-package-json-fast": "^2.0.3"
6589− }
6590− },
6591− "@tootallnate/once": {
6592− "version": "2.0.0",
6593− "bundled": true
6594− },
6595− "abbrev": {
6596− "version": "1.1.1",
6597− "bundled": true
6598− },
6599− "agent-base": {
6600− "version": "6.0.2",
6601− "bundled": true,
6602− "requires": {
6603− "debug": "4"
6604− }
6605− },
6606− "agentkeepalive": {
6607− "version": "4.2.1",
6608− "bundled": true,
6609− "requires": {
6610− "debug": "^4.1.0",
6611− "depd": "^1.1.2",
6612− "humanize-ms": "^1.2.1"
6613− }
6614− },
6615− "aggregate-error": {
6616− "version": "3.1.0",
6617− "bundled": true,
6618− "requires": {
6619− "clean-stack": "^2.0.0",
6620− "indent-string": "^4.0.0"
6621− }
6622− },
6623− "ansi-regex": {
6624− "version": "5.0.1",
6625− "bundled": true
6626− },
6627− "ansi-styles": {
6628− "version": "4.3.0",
6629− "bundled": true,
6630− "requires": {
6631− "color-convert": "^2.0.1"
6632− }
6633− },
6634− "ansicolors": {
6635− "version": "0.3.2",
6636− "bundled": true
6637− },
6638− "ansistyles": {
6639− "version": "0.1.3",
6640− "bundled": true
6641− },
6642− "aproba": {
6643− "version": "2.0.0",
6644− "bundled": true
6645− },
6646− "archy": {
6647− "version": "1.0.0",
6648− "bundled": true
6649− },
6650− "are-we-there-yet": {
6651− "version": "3.0.0",
6652− "bundled": true,
6653− "requires": {
6654− "delegates": "^1.0.0",
6655− "readable-stream": "^3.6.0"
6656− }
6657− },
6658− "asap": {
6659− "version": "2.0.6",
6660− "bundled": true
6661− },
6662− "balanced-match": {
6663− "version": "1.0.2",
6664− "bundled": true
6665− },
6666− "bin-links": {
6667− "version": "3.0.0",
6668− "bundled": true,
6669− "requires": {
6670− "cmd-shim": "^4.0.1",
6671− "mkdirp-infer-owner": "^2.0.0",
6672− "npm-normalize-package-bin": "^1.0.0",
6673− "read-cmd-shim": "^2.0.0",
6674− "rimraf": "^3.0.0",
6675− "write-file-atomic": "^4.0.0"
6676− }
6677− },
6678− "binary-extensions": {
6679− "version": "2.2.0",
6680− "bundled": true
6681− },
6682− "brace-expansion": {
6683− "version": "1.1.11",
6684− "bundled": true,
6685− "requires": {
6686− "balanced-match": "^1.0.0",
6687− "concat-map": "0.0.1"
6688− }
6689− },
6690− "builtins": {
6691− "version": "5.0.0",
6692− "bundled": true,
6693− "requires": {
6694− "semver": "^7.0.0"
6695− }
6696− },
6697− "cacache": {
6698− "version": "16.0.3",
6699− "bundled": true,
6700− "requires": {
6701− "@npmcli/fs": "^2.1.0",
6702− "@npmcli/move-file": "^1.1.2",
6703− "chownr": "^2.0.0",
6704− "fs-minipass": "^2.1.0",
6705− "glob": "^7.2.0",
6706− "infer-owner": "^1.0.4",
6707− "lru-cache": "^7.7.1",
6708− "minipass": "^3.1.6",
6709− "minipass-collect": "^1.0.2",
6710− "minipass-flush": "^1.0.5",
6711− "minipass-pipeline": "^1.2.4",
6712− "mkdirp": "^1.0.4",
6713− "p-map": "^4.0.0",
6714− "promise-inflight": "^1.0.1",
6715− "rimraf": "^3.0.2",
6716− "ssri": "^8.0.1",
6717− "tar": "^6.1.11",
6718− "unique-filename": "^1.1.1"
6719− }
6720− },
6721− "chalk": {
6722− "version": "4.1.2",
6723− "bundled": true,
6724− "requires": {
6725− "ansi-styles": "^4.1.0",
6726− "supports-color": "^7.1.0"
6727− }
6728− },
6729− "chownr": {
6730− "version": "2.0.0",
6731− "bundled": true
6732− },
6733− "cidr-regex": {
6734− "version": "3.1.1",
6735− "bundled": true,
6736− "requires": {
6737− "ip-regex": "^4.1.0"
6738− }
6739− },
6740− "clean-stack": {
6741− "version": "2.2.0",
6742− "bundled": true
6743− },
6744− "cli-columns": {
6745− "version": "4.0.0",
6746− "bundled": true,
6747− "requires": {
6748− "string-width": "^4.2.3",
6749− "strip-ansi": "^6.0.1"
6750− }
6751− },
6752− "cli-table3": {
6753− "version": "0.6.1",
6754− "bundled": true,
6755− "requires": {
6756− "colors": "1.4.0",
6757− "string-width": "^4.2.0"
6758− }
6759− },
6760− "clone": {
6761− "version": "1.0.4",
6762− "bundled": true
6763− },
6764− "cmd-shim": {
6765− "version": "4.1.0",
6766− "bundled": true,
6767− "requires": {
6768− "mkdirp-infer-owner": "^2.0.0"
6769− }
6770− },
6771− "color-convert": {
6772− "version": "2.0.1",
6773− "bundled": true,
6774− "requires": {
6775− "color-name": "~1.1.4"
6776− }
6777− },
6778− "color-name": {
6779− "version": "1.1.4",
6780− "bundled": true
6781− },
6782− "color-support": {
6783− "version": "1.1.3",
6784− "bundled": true
6785− },
6786− "colors": {
6787− "version": "1.4.0",
6788− "bundled": true,
6789− "optional": true
6790− },
6791− "columnify": {
6792− "version": "1.6.0",
6793− "bundled": true,
6794− "requires": {
6795− "strip-ansi": "^6.0.1",
6796− "wcwidth": "^1.0.0"
6797− }
6798− },
6799− "common-ancestor-path": {
6800− "version": "1.0.1",
6801− "bundled": true
6802− },
6803− "concat-map": {
6804− "version": "0.0.1",
6805− "bundled": true
6806− },
6807− "console-control-strings": {
6808− "version": "1.1.0",
6809− "bundled": true
6810− },
6811− "debug": {
6812− "version": "4.3.4",
6813− "bundled": true,
6814− "requires": {
6815− "ms": "2.1.2"
6816− },
6817− "dependencies": {
6818− "ms": {
6819− "version": "2.1.2",
6820− "bundled": true
6821− }
6822− }
6823− },
6824− "debuglog": {
6825− "version": "1.0.1",
6826− "bundled": true
6827− },
6828− "defaults": {
6829− "version": "1.0.3",
6830− "bundled": true,
6831− "requires": {
6832− "clone": "^1.0.2"
6833− }
6834− },
6835− "delegates": {
6836− "version": "1.0.0",
6837− "bundled": true
6838− },
6839− "depd": {
6840− "version": "1.1.2",
6841− "bundled": true
6842− },
6843− "dezalgo": {
6844− "version": "1.0.3",
6845− "bundled": true,
6846− "requires": {
6847− "asap": "^2.0.0",
6848− "wrappy": "1"
6849− }
6850− },
6851− "diff": {
6852− "version": "5.0.0",
6853− "bundled": true
6854− },
6855− "emoji-regex": {
6856− "version": "8.0.0",
6857− "bundled": true
6858− },
6859− "encoding": {
6860− "version": "0.1.13",
6861− "bundled": true,
6862− "optional": true,
6863− "requires": {
6864− "iconv-lite": "^0.6.2"
6865− }
6866− },
6867− "env-paths": {
6868− "version": "2.2.1",
6869− "bundled": true
6870− },
6871− "err-code": {
6872− "version": "2.0.3",
6873− "bundled": true
6874− },
6875− "fastest-levenshtein": {
6876− "version": "1.0.12",
6877− "bundled": true
6878− },
6879− "fs-minipass": {
6880− "version": "2.1.0",
6881− "bundled": true,
6882− "requires": {
6883− "minipass": "^3.0.0"
6884− }
6885− },
6886− "fs.realpath": {
6887− "version": "1.0.0",
6888− "bundled": true
6889− },
6890− "function-bind": {
6891− "version": "1.1.1",
6892− "bundled": true
6893− },
6894− "gauge": {
6895− "version": "4.0.4",
6896− "bundled": true,
6897− "requires": {
6898− "aproba": "^1.0.3 || ^2.0.0",
6899− "color-support": "^1.1.3",
6900− "console-control-strings": "^1.1.0",
6901− "has-unicode": "^2.0.1",
6902− "signal-exit": "^3.0.7",
6903− "string-width": "^4.2.3",
6904− "strip-ansi": "^6.0.1",
6905− "wide-align": "^1.1.5"
6906− }
6907− },
6908− "glob": {
6909− "version": "7.2.0",
6910− "bundled": true,
6911− "requires": {
6912− "fs.realpath": "^1.0.0",
6913− "inflight": "^1.0.4",
6914− "inherits": "2",
6915− "minimatch": "^3.0.4",
6916− "once": "^1.3.0",
6917− "path-is-absolute": "^1.0.0"
6918− }
6919− },
6920− "graceful-fs": {
6921− "version": "4.2.9",
6922− "bundled": true
6923− },
6924− "has": {
6925− "version": "1.0.3",
6926− "bundled": true,
6927− "requires": {
6928− "function-bind": "^1.1.1"
6929− }
6930− },
6931− "has-flag": {
6932− "version": "4.0.0",
6933− "bundled": true
6934− },
6935− "has-unicode": {
6936− "version": "2.0.1",
6937− "bundled": true
6938− },
6939− "hosted-git-info": {
6940− "version": "5.0.0",
6941− "bundled": true,
6942− "requires": {
6943− "lru-cache": "^7.5.1"
6944− }
6945− },
6946− "http-cache-semantics": {
6947− "version": "4.1.0",
6948− "bundled": true
6949− },
6950− "http-proxy-agent": {
6951− "version": "5.0.0",
6952− "bundled": true,
6953− "requires": {
6954− "@tootallnate/once": "2",
6955− "agent-base": "6",
6956− "debug": "4"
6957− }
6958− },
6959− "https-proxy-agent": {
6960− "version": "5.0.0",
6961− "bundled": true,
6962− "requires": {
6963− "agent-base": "6",
6964− "debug": "4"
6965− }
6966− },
6967− "humanize-ms": {
6968− "version": "1.2.1",
6969− "bundled": true,
6970− "requires": {
6971− "ms": "^2.0.0"
6972− }
6973− },
6974− "iconv-lite": {
6975− "version": "0.6.3",
6976− "bundled": true,
6977− "optional": true,
6978− "requires": {
6979− "safer-buffer": ">= 2.1.2 < 3.0.0"
6980− }
6981− },
6982− "ignore-walk": {
6983− "version": "4.0.1",
6984− "bundled": true,
6985− "requires": {
6986− "minimatch": "^3.0.4"
6987− }
6988− },
6989− "imurmurhash": {
6990− "version": "0.1.4",
6991− "bundled": true
6992− },
6993− "indent-string": {
6994− "version": "4.0.0",
6995− "bundled": true
6996− },
6997− "infer-owner": {
6998− "version": "1.0.4",
6999− "bundled": true
7000− },
7001− "inflight": {
7002− "version": "1.0.6",
7003− "bundled": true,
7004− "requires": {
7005− "once": "^1.3.0",
7006− "wrappy": "1"
7007− }
7008− },
7009− "inherits": {
7010− "version": "2.0.4",
7011− "bundled": true
7012− },
7013− "ini": {
7014− "version": "2.0.0",
7015− "bundled": true
7016− },
7017− "init-package-json": {
7018− "version": "3.0.2",
7019− "bundled": true,
7020− "requires": {
7021− "npm-package-arg": "^9.0.1",
7022− "promzard": "^0.3.0",
7023− "read": "^1.0.7",
7024− "read-package-json": "^5.0.0",
7025− "semver": "^7.3.5",
7026− "validate-npm-package-license": "^3.0.4",
7027− "validate-npm-package-name": "^4.0.0"
7028− }
7029− },
7030− "ip": {
7031− "version": "1.1.5",
7032− "bundled": true
7033− },
7034− "ip-regex": {
7035− "version": "4.3.0",
7036− "bundled": true
7037− },
7038− "is-cidr": {
7039− "version": "4.0.2",
7040− "bundled": true,
7041− "requires": {
7042− "cidr-regex": "^3.1.1"
7043− }
7044− },
7045− "is-core-module": {
7046− "version": "2.8.1",
7047− "bundled": true,
7048− "requires": {
7049− "has": "^1.0.3"
7050− }
7051− },
7052− "is-fullwidth-code-point": {
7053− "version": "3.0.0",
7054− "bundled": true
7055− },
7056− "is-lambda": {
7057− "version": "1.0.1",
7058− "bundled": true
7059− },
7060− "isexe": {
7061− "version": "2.0.0",
7062− "bundled": true
7063− },
7064− "json-parse-even-better-errors": {
7065− "version": "2.3.1",
7066− "bundled": true
7067− },
7068− "json-stringify-nice": {
7069− "version": "1.1.4",
7070− "bundled": true
7071− },
7072− "jsonparse": {
7073− "version": "1.3.1",
7074− "bundled": true
7075− },
7076− "just-diff": {
7077− "version": "5.0.1",
7078− "bundled": true
7079− },
7080− "just-diff-apply": {
7081− "version": "5.2.0",
7082− "bundled": true
7083− },
7084− "libnpmaccess": {
7085− "version": "6.0.2",
7086− "bundled": true,
7087− "requires": {
7088− "aproba": "^2.0.0",
7089− "minipass": "^3.1.1",
7090− "npm-package-arg": "^9.0.1",
7091− "npm-registry-fetch": "^13.0.0"
7092− }
7093− },
7094− "libnpmdiff": {
7095− "version": "4.0.2",
7096− "bundled": true,
7097− "requires": {
7098− "@npmcli/disparity-colors": "^1.0.1",
7099− "@npmcli/installed-package-contents": "^1.0.7",
7100− "binary-extensions": "^2.2.0",
7101− "diff": "^5.0.0",
7102− "minimatch": "^3.0.4",
7103− "npm-package-arg": "^9.0.1",
7104− "pacote": "^13.0.5",
7105− "tar": "^6.1.0"
7106− }
7107− },
7108− "libnpmexec": {
7109− "version": "4.0.2",
7110− "bundled": true,
7111− "requires": {
7112− "@npmcli/arborist": "^5.0.0",
7113− "@npmcli/ci-detect": "^2.0.0",
7114− "@npmcli/run-script": "^3.0.0",
7115− "chalk": "^4.1.0",
7116− "mkdirp-infer-owner": "^2.0.0",
7117− "npm-package-arg": "^9.0.1",
7118− "npmlog": "^6.0.1",
7119− "pacote": "^13.0.5",
7120− "proc-log": "^2.0.0",
7121− "read": "^1.0.7",
7122− "read-package-json-fast": "^2.0.2",
7123− "walk-up-path": "^1.0.0"
7124− }
7125− },
7126− "libnpmfund": {
7127− "version": "3.0.1",
7128− "bundled": true,
7129− "requires": {
7130− "@npmcli/arborist": "^5.0.0"
7131− }
7132− },
7133− "libnpmhook": {
7134− "version": "8.0.2",
7135− "bundled": true,
7136− "requires": {
7137− "aproba": "^2.0.0",
7138− "npm-registry-fetch": "^13.0.0"
7139− }
7140− },
7141− "libnpmorg": {
7142− "version": "4.0.2",
7143− "bundled": true,
7144− "requires": {
7145− "aproba": "^2.0.0",
7146− "npm-registry-fetch": "^13.0.0"
7147− }
7148− },
7149− "libnpmpack": {
7150− "version": "4.0.2",
7151− "bundled": true,
7152− "requires": {
7153− "@npmcli/run-script": "^3.0.0",
7154− "npm-package-arg": "^9.0.1",
7155− "pacote": "^13.0.5"
7156− }
7157− },
7158− "libnpmpublish": {
7159− "version": "6.0.2",
7160− "bundled": true,
7161− "requires": {
7162− "normalize-package-data": "^4.0.0",
7163− "npm-package-arg": "^9.0.1",
7164− "npm-registry-fetch": "^13.0.0",
7165− "semver": "^7.1.3",
7166− "ssri": "^8.0.1"
7167− }
7168− },
7169− "libnpmsearch": {
7170− "version": "5.0.2",
7171− "bundled": true,
7172− "requires": {
7173− "npm-registry-fetch": "^13.0.0"
7174− }
7175− },
7176− "libnpmteam": {
7177− "version": "4.0.2",
7178− "bundled": true,
7179− "requires": {
7180− "aproba": "^2.0.0",
7181− "npm-registry-fetch": "^13.0.0"
7182− }
7183− },
7184− "libnpmversion": {
7185− "version": "3.0.1",
7186− "bundled": true,
7187− "requires": {
7188− "@npmcli/git": "^3.0.0",
7189− "@npmcli/run-script": "^3.0.0",
7190− "json-parse-even-better-errors": "^2.3.1",
7191− "proc-log": "^2.0.0",
7192− "semver": "^7.3.5",
7193− "stringify-package": "^1.0.1"
7194− }
7195− },
7196− "lru-cache": {
7197− "version": "7.7.1",
7198− "bundled": true
7199− },
7200− "make-fetch-happen": {
7201− "version": "10.1.1",
7202− "bundled": true,
7203− "requires": {
7204− "agentkeepalive": "^4.2.1",
7205− "cacache": "^16.0.2",
7206− "http-cache-semantics": "^4.1.0",
7207− "http-proxy-agent": "^5.0.0",
7208− "https-proxy-agent": "^5.0.0",
7209− "is-lambda": "^1.0.1",
7210− "lru-cache": "^7.7.1",
7211− "minipass": "^3.1.6",
7212− "minipass-collect": "^1.0.2",
7213− "minipass-fetch": "^2.0.3",
7214− "minipass-flush": "^1.0.5",
7215− "minipass-pipeline": "^1.2.4",
7216− "negotiator": "^0.6.3",
7217− "promise-retry": "^2.0.1",
7218− "socks-proxy-agent": "^6.1.1",
7219− "ssri": "^8.0.1"
7220− }
7221− },
7222− "minimatch": {
7223− "version": "3.1.2",
7224− "bundled": true,
7225− "requires": {
7226− "brace-expansion": "^1.1.7"
7227− }
7228− },
7229− "minipass": {
7230− "version": "3.1.6",
7231− "bundled": true,
7232− "requires": {
7233− "yallist": "^4.0.0"
7234− }
7235− },
7236− "minipass-collect": {
7237− "version": "1.0.2",
7238− "bundled": true,
7239− "requires": {
7240− "minipass": "^3.0.0"
7241− }
7242− },
7243− "minipass-fetch": {
7244− "version": "2.1.0",
7245− "bundled": true,
7246− "requires": {
7247− "encoding": "^0.1.13",
7248− "minipass": "^3.1.6",
7249− "minipass-sized": "^1.0.3",
7250− "minizlib": "^2.1.2"
7251− }
7252− },
7253− "minipass-flush": {
7254− "version": "1.0.5",
7255− "bundled": true,
7256− "requires": {
7257− "minipass": "^3.0.0"
7258− }
7259− },
7260− "minipass-json-stream": {
7261− "version": "1.0.1",
7262− "bundled": true,
7263− "requires": {
7264− "jsonparse": "^1.3.1",
7265− "minipass": "^3.0.0"
7266− }
7267− },
7268− "minipass-pipeline": {
7269− "version": "1.2.4",
7270− "bundled": true,
7271− "requires": {
7272− "minipass": "^3.0.0"
7273− }
7274− },
7275− "minipass-sized": {
7276− "version": "1.0.3",
7277− "bundled": true,
7278− "requires": {
7279− "minipass": "^3.0.0"
7280− }
7281− },
7282− "minizlib": {
7283− "version": "2.1.2",
7284− "bundled": true,
7285− "requires": {
7286− "minipass": "^3.0.0",
7287− "yallist": "^4.0.0"
7288− }
7289− },
7290− "mkdirp": {
7291− "version": "1.0.4",
7292− "bundled": true
7293− },
7294− "mkdirp-infer-owner": {
7295− "version": "2.0.0",
7296− "bundled": true,
7297− "requires": {
7298− "chownr": "^2.0.0",
7299− "infer-owner": "^1.0.4",
7300− "mkdirp": "^1.0.3"
7301− }
7302− },
7303− "ms": {
7304− "version": "2.1.3",
7305− "bundled": true
7306− },
7307− "mute-stream": {
7308− "version": "0.0.8",
7309− "bundled": true
7310− },
7311− "negotiator": {
7312− "version": "0.6.3",
7313− "bundled": true
7314− },
7315− "node-gyp": {
7316− "version": "9.0.0",
7317− "bundled": true,
7318− "requires": {
7319− "env-paths": "^2.2.0",
7320− "glob": "^7.1.4",
7321− "graceful-fs": "^4.2.6",
7322− "make-fetch-happen": "^10.0.3",
7323− "nopt": "^5.0.0",
7324− "npmlog": "^6.0.0",
7325− "rimraf": "^3.0.2",
7326− "semver": "^7.3.5",
7327− "tar": "^6.1.2",
7328− "which": "^2.0.2"
7329− }
7330− },
7331− "nopt": {
7332− "version": "5.0.0",
7333− "bundled": true,
7334− "requires": {
7335− "abbrev": "1"
7336− }
7337− },
7338− "normalize-package-data": {
7339− "version": "4.0.0",
7340− "bundled": true,
7341− "requires": {
7342− "hosted-git-info": "^5.0.0",
7343− "is-core-module": "^2.8.1",
7344− "semver": "^7.3.5",
7345− "validate-npm-package-license": "^3.0.4"
7346− }
7347− },
7348− "npm-audit-report": {
7349− "version": "3.0.0",
7350− "bundled": true,
7351− "requires": {
7352− "chalk": "^4.0.0"
7353− }
7354− },
7355− "npm-bundled": {
7356− "version": "1.1.2",
7357− "bundled": true,
7358− "requires": {
7359− "npm-normalize-package-bin": "^1.0.1"
7360− }
7361− },
7362− "npm-install-checks": {
7363− "version": "4.0.0",
7364− "bundled": true,
7365− "requires": {
7366− "semver": "^7.1.1"
7367− }
7368− },
7369− "npm-normalize-package-bin": {
7370− "version": "1.0.1",
7371− "bundled": true
7372− },
7373− "npm-package-arg": {
7374− "version": "9.0.2",
7375− "bundled": true,
7376− "requires": {
7377− "hosted-git-info": "^5.0.0",
7378− "semver": "^7.3.5",
7379− "validate-npm-package-name": "^4.0.0"
7380− }
7381− },
7382− "npm-packlist": {
7383− "version": "4.0.0",
7384− "bundled": true,
7385− "requires": {
7386− "glob": "^7.2.0",
7387− "ignore-walk": "^4.0.1",
7388− "npm-bundled": "^1.1.2",
7389− "npm-normalize-package-bin": "^1.0.1"
7390− }
7391− },
7392− "npm-pick-manifest": {
7393− "version": "7.0.0",
7394− "bundled": true,
7395− "requires": {
7396− "npm-install-checks": "^4.0.0",
7397− "npm-normalize-package-bin": "^1.0.1",
7398− "npm-package-arg": "^9.0.0",
7399− "semver": "^7.3.5"
7400− }
7401− },
7402− "npm-profile": {
7403− "version": "6.0.2",
7404− "bundled": true,
7405− "requires": {
7406− "npm-registry-fetch": "^13.0.0",
7407− "proc-log": "^2.0.0"
7408− }
7409− },
7410− "npm-registry-fetch": {
7411− "version": "13.1.0",
7412− "bundled": true,
7413− "requires": {
7414− "make-fetch-happen": "^10.0.6",
7415− "minipass": "^3.1.6",
7416− "minipass-fetch": "^2.0.3",
7417− "minipass-json-stream": "^1.0.1",
7418− "minizlib": "^2.1.2",
7419− "npm-package-arg": "^9.0.1",
7420− "proc-log": "^2.0.0"
7421− }
7422− },
7423− "npm-user-validate": {
7424− "version": "1.0.1",
7425− "bundled": true
7426− },
7427− "npmlog": {
7428− "version": "6.0.1",
7429− "bundled": true,
7430− "requires": {
7431− "are-we-there-yet": "^3.0.0",
7432− "console-control-strings": "^1.1.0",
7433− "gauge": "^4.0.0",
7434− "set-blocking": "^2.0.0"
7435− }
7436− },
7437− "once": {
7438− "version": "1.4.0",
7439− "bundled": true,
7440− "requires": {
7441− "wrappy": "1"
7442− }
7443− },
7444− "opener": {
7445− "version": "1.5.2",
7446− "bundled": true
7447− },
7448− "p-map": {
7449− "version": "4.0.0",
7450− "bundled": true,
7451− "requires": {
7452− "aggregate-error": "^3.0.0"
7453− }
7454− },
7455− "pacote": {
7456− "version": "13.0.5",
7457− "bundled": true,
7458− "requires": {
7459− "@npmcli/git": "^3.0.0",
7460− "@npmcli/installed-package-contents": "^1.0.7",
7461− "@npmcli/promise-spawn": "^1.2.0",
7462− "@npmcli/run-script": "^3.0.1",
7463− "cacache": "^16.0.0",
7464− "chownr": "^2.0.0",
7465− "fs-minipass": "^2.1.0",
7466− "infer-owner": "^1.0.4",
7467− "minipass": "^3.1.6",
7468− "mkdirp": "^1.0.4",
7469− "npm-package-arg": "^9.0.0",
7470− "npm-packlist": "^4.0.0",
7471− "npm-pick-manifest": "^7.0.0",
7472− "npm-registry-fetch": "^13.0.1",
7473− "proc-log": "^2.0.0",
7474− "promise-retry": "^2.0.1",
7475− "read-package-json": "^5.0.0",
7476− "read-package-json-fast": "^2.0.3",
7477− "rimraf": "^3.0.2",
7478− "ssri": "^8.0.1",
7479− "tar": "^6.1.11"
7480− }
7481− },
7482− "parse-conflict-json": {
7483− "version": "2.0.2",
7484− "bundled": true,
7485− "requires": {
7486− "json-parse-even-better-errors": "^2.3.1",
7487− "just-diff": "^5.0.1",
7488− "just-diff-apply": "^5.2.0"
7489− }
7490− },
7491− "path-is-absolute": {
7492− "version": "1.0.1",
7493− "bundled": true
7494− },
7495− "proc-log": {
7496− "version": "2.0.1",
7497− "bundled": true
7498− },
7499− "promise-all-reject-late": {
7500− "version": "1.0.1",
7501− "bundled": true
7502− },
7503− "promise-call-limit": {
7504− "version": "1.0.1",
7505− "bundled": true
7506− },
7507− "promise-inflight": {
7508− "version": "1.0.1",
7509− "bundled": true
7510− },
7511− "promise-retry": {
7512− "version": "2.0.1",
7513− "bundled": true,
7514− "requires": {
7515− "err-code": "^2.0.2",
7516− "retry": "^0.12.0"
7517− }
7518− },
7519− "promzard": {
7520− "version": "0.3.0",
7521− "bundled": true,
7522− "requires": {
7523− "read": "1"
7524− }
7525− },
7526− "qrcode-terminal": {
7527− "version": "0.12.0",
7528− "bundled": true
7529− },
7530− "read": {
7531− "version": "1.0.7",
7532− "bundled": true,
7533− "requires": {
7534− "mute-stream": "~0.0.4"
7535− }
7536− },
7537− "read-cmd-shim": {
7538− "version": "2.0.0",
7539− "bundled": true
7540− },
7541− "read-package-json": {
7542− "version": "5.0.0",
7543− "bundled": true,
7544− "requires": {
7545− "glob": "^7.2.0",
7546− "json-parse-even-better-errors": "^2.3.1",
7547− "normalize-package-data": "^4.0.0",
7548− "npm-normalize-package-bin": "^1.0.1"
7549− }
7550− },
7551− "read-package-json-fast": {
7552− "version": "2.0.3",
7553− "bundled": true,
7554− "requires": {
7555− "json-parse-even-better-errors": "^2.3.0",
7556− "npm-normalize-package-bin": "^1.0.1"
7557− }
7558− },
7559− "readable-stream": {
7560− "version": "3.6.0",
7561− "bundled": true,
7562− "requires": {
7563− "inherits": "^2.0.3",
7564− "string_decoder": "^1.1.1",
7565− "util-deprecate": "^1.0.1"
7566− }
7567− },
7568− "readdir-scoped-modules": {
7569− "version": "1.1.0",
7570− "bundled": true,
7571− "requires": {
7572− "debuglog": "^1.0.1",
7573− "dezalgo": "^1.0.0",
7574− "graceful-fs": "^4.1.2",
7575− "once": "^1.3.0"
7576− }
7577− },
7578− "retry": {
7579− "version": "0.12.0",
7580− "bundled": true
7581− },
7582− "rimraf": {
7583− "version": "3.0.2",
7584− "bundled": true,
7585− "requires": {
7586− "glob": "^7.1.3"
7587− }
7588− },
7589− "safe-buffer": {
7590− "version": "5.2.1",
7591− "bundled": true
7592− },
7593− "safer-buffer": {
7594− "version": "2.1.2",
7595− "bundled": true,
7596− "optional": true
7597− },
7598− "semver": {
7599− "version": "7.3.5",
7600− "bundled": true,
7601− "requires": {
7602− "lru-cache": "^6.0.0"
7603− },
7604− "dependencies": {
7605− "lru-cache": {
7606− "version": "6.0.0",
7607− "bundled": true,
7608− "requires": {
7609− "yallist": "^4.0.0"
7610− }
7611− }
7612− }
7613− },
7614− "set-blocking": {
7615− "version": "2.0.0",
7616− "bundled": true
7617− },
7618− "signal-exit": {
7619− "version": "3.0.7",
7620− "bundled": true
7621− },
7622− "smart-buffer": {
7623− "version": "4.2.0",
7624− "bundled": true
7625− },
7626− "socks": {
7627− "version": "2.6.2",
7628− "bundled": true,
7629− "requires": {
7630− "ip": "^1.1.5",
7631− "smart-buffer": "^4.2.0"
7632− }
7633− },
7634− "socks-proxy-agent": {
7635− "version": "6.1.1",
7636− "bundled": true,
7637− "requires": {
7638− "agent-base": "^6.0.2",
7639− "debug": "^4.3.1",
7640− "socks": "^2.6.1"
7641− }
7642− },
7643− "spdx-correct": {
7644− "version": "3.1.1",
7645− "bundled": true,
7646− "requires": {
7647− "spdx-expression-parse": "^3.0.0",
7648− "spdx-license-ids": "^3.0.0"
7649− }
7650− },
7651− "spdx-exceptions": {
7652− "version": "2.3.0",
7653− "bundled": true
7654− },
7655− "spdx-expression-parse": {
7656− "version": "3.0.1",
7657− "bundled": true,
7658− "requires": {
7659− "spdx-exceptions": "^2.1.0",
7660− "spdx-license-ids": "^3.0.0"
7661− }
7662− },
7663− "spdx-license-ids": {
7664− "version": "3.0.11",
7665− "bundled": true
7666− },
7667− "ssri": {
7668− "version": "8.0.1",
7669− "bundled": true,
7670− "requires": {
7671− "minipass": "^3.1.1"
7672− }
7673− },
7674− "string_decoder": {
7675− "version": "1.3.0",
7676− "bundled": true,
7677− "requires": {
7678− "safe-buffer": "~5.2.0"
7679− }
7680− },
7681− "string-width": {
7682− "version": "4.2.3",
7683− "bundled": true,
7684− "requires": {
7685− "emoji-regex": "^8.0.0",
7686− "is-fullwidth-code-point": "^3.0.0",
7687− "strip-ansi": "^6.0.1"
7688− }
7689− },
7690− "stringify-package": {
7691− "version": "1.0.1",
7692− "bundled": true
7693− },
7694− "strip-ansi": {
7695− "version": "6.0.1",
7696− "bundled": true,
7697− "requires": {
7698− "ansi-regex": "^5.0.1"
7699− }
7700− },
7701− "supports-color": {
7702− "version": "7.2.0",
7703− "bundled": true,
7704− "requires": {
7705− "has-flag": "^4.0.0"
7706− }
7707− },
7708− "tar": {
7709− "version": "6.1.11",
7710− "bundled": true,
7711− "requires": {
7712− "chownr": "^2.0.0",
7713− "fs-minipass": "^2.0.0",
7714− "minipass": "^3.0.0",
7715− "minizlib": "^2.1.1",
7716− "mkdirp": "^1.0.3",
7717− "yallist": "^4.0.0"
7718− }
7719− },
7720− "text-table": {
7721− "version": "0.2.0",
7722− "bundled": true
7723− },
7724− "tiny-relative-date": {
7725− "version": "1.3.0",
7726− "bundled": true
7727− },
7728− "treeverse": {
7729− "version": "1.0.4",
7730− "bundled": true
7731− },
7732− "unique-filename": {
7733− "version": "1.1.1",
7734− "bundled": true,
7735− "requires": {
7736− "unique-slug": "^2.0.0"
7737− }
7738− },
7739− "unique-slug": {
7740− "version": "2.0.2",
7741− "bundled": true,
7742− "requires": {
7743− "imurmurhash": "^0.1.4"
7744− }
7745− },
7746− "util-deprecate": {
7747− "version": "1.0.2",
7748− "bundled": true
7749− },
7750− "validate-npm-package-license": {
7751− "version": "3.0.4",
7752− "bundled": true,
7753− "requires": {
7754− "spdx-correct": "^3.0.0",
7755− "spdx-expression-parse": "^3.0.0"
7756− }
7757− },
7758− "validate-npm-package-name": {
7759− "version": "4.0.0",
7760− "bundled": true,
7761− "requires": {
7762− "builtins": "^5.0.0"
7763− }
7764− },
7765− "walk-up-path": {
7766− "version": "1.0.0",
7767− "bundled": true
7768− },
7769− "wcwidth": {
7770− "version": "1.0.1",
7771− "bundled": true,
7772− "requires": {
7773− "defaults": "^1.0.3"
7774− }
7775− },
7776− "which": {
7777− "version": "2.0.2",
7778− "bundled": true,
7779− "requires": {
7780− "isexe": "^2.0.0"
7781− }
7782− },
7783− "wide-align": {
7784− "version": "1.1.5",
7785− "bundled": true,
7786− "requires": {
7787− "string-width": "^1.0.2 || 2 || 3 || 4"
7788− }
7789− },
7790− "wrappy": {
7791− "version": "1.0.2",
7792− "bundled": true
7793− },
7794− "write-file-atomic": {
7795− "version": "4.0.1",
7796− "bundled": true,
7797− "requires": {
7798− "imurmurhash": "^0.1.4",
7799− "signal-exit": "^3.0.7"
7800− }
7801− },
7802− "yallist": {
7803− "version": "4.0.0",
7804− "bundled": true
7805− }
4142+ "loose-envify": "^1.0.0"
78064143 }
78074144 },
4145+ "is-arrayish": {
4146+ "version": "0.2.1",
4147+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
4148+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
4149+ "dev": true
4150+ },
4151+ "is-binary-path": {
4152+ "version": "2.1.0",
4153+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
4154+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
4155+ "dev": true,
4156+ "requires": {
4157+ "binary-extensions": "^2.0.0"
4158+ }
4159+ },
4160+ "is-buffer": {
4161+ "version": "1.1.6",
4162+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
4163+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
4164+ },
4165+ "is-core-module": {
4166+ "version": "2.8.1",
4167+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
4168+ "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
4169+ "dev": true,
4170+ "requires": {
4171+ "has": "^1.0.3"
4172+ }
4173+ },
4174+ "is-extglob": {
4175+ "version": "2.1.1",
4176+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
4177+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
4178+ "dev": true
4179+ },
4180+ "is-fullwidth-code-point": {
4181+ "version": "3.0.0",
4182+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
4183+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
4184+ "dev": true
4185+ },
4186+ "is-glob": {
4187+ "version": "4.0.3",
4188+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
4189+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
4190+ "dev": true,
4191+ "requires": {
4192+ "is-extglob": "^2.1.1"
4193+ }
4194+ },
4195+ "is-number": {
4196+ "version": "7.0.0",
4197+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
4198+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
4199+ "dev": true
4200+ },
4201+ "is-plain-object": {
4202+ "version": "2.0.4",
4203+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
4204+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
4205+ "requires": {
4206+ "isobject": "^3.0.1"
4207+ }
4208+ },
4209+ "isarray": {
4210+ "version": "1.0.0",
4211+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
4212+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
4213+ },
4214+ "isexe": {
4215+ "version": "2.0.0",
4216+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
4217+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
4218+ "dev": true
4219+ },
4220+ "isobject": {
4221+ "version": "3.0.1",
4222+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
4223+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="
4224+ },
4225+ "js-tokens": {
4226+ "version": "4.0.0",
4227+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
4228+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
4229+ },
4230+ "json-parse-even-better-errors": {
4231+ "version": "2.3.1",
4232+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
4233+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
4234+ "dev": true
4235+ },
4236+ "jsonfile": {
4237+ "version": "6.1.0",
4238+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
4239+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
4240+ "dev": true,
4241+ "requires": {
4242+ "graceful-fs": "^4.1.6",
4243+ "universalify": "^2.0.0"
4244+ }
4245+ },
4246+ "kind-of": {
4247+ "version": "3.2.2",
4248+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
4249+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
4250+ "requires": {
4251+ "is-buffer": "^1.1.5"
4252+ }
4253+ },
4254+ "kleur": {
4255+ "version": "4.1.4",
4256+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
4257+ "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==",
4258+ "dev": true
4259+ },
4260+ "lilconfig": {
4261+ "version": "2.0.4",
4262+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz",
4263+ "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==",
4264+ "dev": true
4265+ },
4266+ "lines-and-columns": {
4267+ "version": "1.2.4",
4268+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
4269+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
4270+ "dev": true
4271+ },
4272+ "lodash": {
4273+ "version": "4.17.21",
4274+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
4275+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
4276+ },
4277+ "lodash.chunk": {
4278+ "version": "4.2.0",
4279+ "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz",
4280+ "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw="
4281+ },
4282+ "lodash.isequal": {
4283+ "version": "4.5.0",
4284+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
4285+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
4286+ },
4287+ "loose-envify": {
4288+ "version": "1.4.0",
4289+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
4290+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
4291+ "requires": {
4292+ "js-tokens": "^3.0.0 || ^4.0.0"
4293+ }
4294+ },
4295+ "magic-string": {
4296+ "version": "0.25.7",
4297+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
4298+ "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
4299+ "dev": true,
4300+ "requires": {
4301+ "sourcemap-codec": "^1.4.4"
4302+ }
4303+ },
4304+ "marked": {
4305+ "version": "4.2.3",
4306+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz",
4307+ "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw=="
4308+ },
4309+ "merge2": {
4310+ "version": "1.4.1",
4311+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
4312+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
4313+ "dev": true
4314+ },
4315+ "micromatch": {
4316+ "version": "4.0.4",
4317+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
4318+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
4319+ "dev": true,
4320+ "requires": {
4321+ "braces": "^3.0.1",
4322+ "picomatch": "^2.2.3"
4323+ }
4324+ },
4325+ "min-indent": {
4326+ "version": "1.0.1",
4327+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
4328+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
4329+ "dev": true
4330+ },
4331+ "minimatch": {
4332+ "version": "3.0.4",
4333+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
4334+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
4335+ "dev": true,
4336+ "requires": {
4337+ "brace-expansion": "^1.1.7"
4338+ }
4339+ },
4340+ "minimist": {
4341+ "version": "1.2.6",
4342+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
4343+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
4344+ "dev": true
4345+ },
4346+ "mkdirp": {
4347+ "version": "0.5.5",
4348+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
4349+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
4350+ "dev": true,
4351+ "requires": {
4352+ "minimist": "^1.2.5"
4353+ }
4354+ },
4355+ "mri": {
4356+ "version": "1.2.0",
4357+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
4358+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
4359+ "dev": true
4360+ },
4361+ "ms": {
4362+ "version": "2.1.2",
4363+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
4364+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
4365+ "dev": true
4366+ },
4367+ "nanoid": {
4368+ "version": "3.3.1",
4369+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
4370+ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
4371+ "dev": true
4372+ },
4373+ "node-releases": {
4374+ "version": "2.0.1",
4375+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz",
4376+ "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==",
4377+ "dev": true
4378+ },
4379+ "normalize-path": {
4380+ "version": "3.0.0",
4381+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
4382+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
4383+ "dev": true
4384+ },
4385+ "normalize-range": {
4386+ "version": "0.1.2",
4387+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
4388+ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
4389+ "dev": true
4390+ },
78084391 "object-assign": {
78094392 "version": "4.1.1",
78104393 "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
7811− "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
4394+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
78124395 "peer": true
78134396 },
78144397 "object-hash": {
@@ -7817,10 +4400,15 @@
78174400 "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
78184401 "dev": true
78194402 },
4403+ "obliterator": {
4404+ "version": "2.0.4",
4405+ "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz",
4406+ "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ=="
4407+ },
78204408 "omit-deep": {
78214409 "version": "0.3.0",
78224410 "resolved": "https://registry.npmjs.org/omit-deep/-/omit-deep-0.3.0.tgz",
7823− "integrity": "sha1-IcivNJm8rdKWUaIyy8rLxSRF6+w=",
4411+ "integrity": "sha512-Lbl/Ma59sss2b15DpnWnGmECBRL8cRl/PjPbPMVW+Y8zIQzRrwMaI65Oy6HvxyhYeILVKBJb2LWeG81bj5zbMg==",
78244412 "requires": {
78254413 "is-plain-object": "^2.0.1",
78264414 "unset-value": "^0.1.1"
@@ -7889,7 +4477,8 @@
78894477 "picomatch": {
78904478 "version": "2.3.1",
78914479 "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
7892− "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
4480+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
4481+ "dev": true
78934482 },
78944483 "pify": {
78954484 "version": "2.3.0",
@@ -8046,6 +4635,7 @@
80464635 "version": "3.6.0",
80474636 "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
80484637 "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
4638+ "dev": true,
80494639 "requires": {
80504640 "picomatch": "^2.2.1"
80514641 }
@@ -8170,6 +4760,7 @@
81704760 "version": "1.50.0",
81714761 "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz",
81724762 "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==",
4763+ "dev": true,
81734764 "requires": {
81744765 "chokidar": ">=3.0.0 <4.0.0",
81754766 "immutable": "^4.0.0",
@@ -8191,6 +4782,16 @@
81914782 "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
81924783 "dev": true
81934784 },
4785+ "sigma-jh": {
4786+ "version": "2.4.2",
4787+ "resolved": "https://registry.npmjs.org/sigma-jh/-/sigma-jh-2.4.2.tgz",
4788+ "integrity": "sha512-viB4M5Y79N5rAgs0z3M4Gff4HX53S+UMwblPDEH/Nkwwe7AcmcWwsEYsGv/xL/TNQzLIBBb0NaNAg5ZhnbEm8g==",
4789+ "requires": {
4790+ "@yomguithereal/helpers": "^1.1.1",
4791+ "events": "^3.3.0",
4792+ "graphology-utils": "^2.5.0"
4793+ }
4794+ },
81944795 "slash": {
81954796 "version": "4.0.0",
81964797 "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
@@ -8218,7 +4819,8 @@
82184819 "source-map-js": {
82194820 "version": "1.0.1",
82204821 "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
8221− "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA=="
4822+ "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
4823+ "dev": true
82224824 },
82234825 "sourcemap-codec": {
82244826 "version": "1.4.8",
@@ -8277,10 +4879,9 @@
82774879 "dev": true
82784880 },
82794881 "svelte": {
8280− "version": "3.45.0",
8281− "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.45.0.tgz",
8282− "integrity": "sha512-6AWftH2eqqKLYH1HvKpuUWe8OfjflarhegN57P/Cqwc2Rb2F5oIdDtANU/jMscyZMzG0v6nTQox0siZR9cmRVQ==",
8283− "dev": true
4882+ "version": "3.48.0",
4883+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.48.0.tgz",
4884+ "integrity": "sha512-fN2YRm/bGumvjUpu6yI3BpvZnpIm9I6A7HR4oUNYd7ggYyIwSA/BX7DJ+UXXffLp6XNcUijyLvttbPVCYa/3xQ=="
82844885 },
82854886 "svelte-check": {
82864887 "version": "2.2.11",
@@ -8311,6 +4912,15 @@
83114912 "dev": true,
83124913 "requires": {}
83134914 },
4915+ "svelte-markdown": {
4916+ "version": "0.2.3",
4917+ "resolved": "https://registry.npmjs.org/svelte-markdown/-/svelte-markdown-0.2.3.tgz",
4918+ "integrity": "sha512-2h680NzTXnAD0CXhxe3GeHl6W+ayG4iKQRl+BIDRw+R0mUE0OiNxP1Vt8Rn+aWevB/LBiBIPCAwvL+0BkG057A==",
4919+ "requires": {
4920+ "@types/marked": "^4.0.1",
4921+ "marked": "^4.0.10"
4922+ }
4923+ },
83144924 "svelte-preprocess": {
83154925 "version": "4.10.1",
83164926 "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.10.1.tgz",
@@ -8401,6 +5011,7 @@
84015011 "version": "5.0.1",
84025012 "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
84035013 "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
5014+ "dev": true,
84045015 "requires": {
84055016 "is-number": "^7.0.0"
84065017 }
@@ -8437,7 +5048,7 @@
84375048 "unset-value": {
84385049 "version": "0.1.2",
84395050 "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz",
8440− "integrity": "sha1-UGgQuGfyfCpabpsEgzYx9t5Y0xA=",
5051+ "integrity": "sha512-yhv5I4TsldLdE3UcVQn0hD2T5sNCPv4+qm/CTUpRKIpwthYRIipsAPdsrNpOI79hPQa0rTTeW22Fq6JWRcTgNg==",
84415052 "requires": {
84425053 "has-value": "^0.3.1",
84435054 "isobject": "^3.0.0"
@@ -8524,7 +5135,7 @@
85245135 "xml-lexer": {
85255136 "version": "0.2.2",
85265137 "resolved": "https://registry.npmjs.org/xml-lexer/-/xml-lexer-0.2.2.tgz",
8527− "integrity": "sha1-UYGTpKozTVj8fSSLVJB5uJkH4EY=",
5138+ "integrity": "sha512-G0i98epIwiUEiKmMcavmVdhtymW+pCAohMRgybyIME9ygfVu8QheIi+YoQh3ngiThsT0SQzJT4R0sKDEv8Ou0w==",
85285139 "requires": {
85295140 "eventemitter3": "^2.0.0"
85305141 }
@@ -8532,7 +5143,7 @@
85325143 "xml-reader": {
85335144 "version": "2.4.3",
85345145 "resolved": "https://registry.npmjs.org/xml-reader/-/xml-reader-2.4.3.tgz",
8535− "integrity": "sha1-n4EMr3xCWlqvuEixxFEDyecddTA=",
5146+ "integrity": "sha512-xWldrIxjeAMAu6+HSf9t50ot1uL5M+BtOidRCWHXIeewvSeIpscWCsp4Zxjk8kHHhdqFBrfK8U0EJeCcnyQ/gA==",
85365147 "requires": {
85375148 "eventemitter3": "^2.0.0",
85385149 "xml-lexer": "^0.2.2"
ui/package.json+24−10
@@ -1,17 +1,27 @@
11{
22 "name": "urbit-astrolabe",
3− "version": "0.0.0",
43 "type": "module",
4+ "version": "0.3.0",
55 "scripts": {
6− "dev:only": "vite --port 4000",
7− "build:only": "vite build",
6+ "dev:vite": "vite --port 4000 --host",
7+ "build:vite": "vite build",
88 "tailwind:watch": "cross-env TAILWIND_MODE=watch cross-env NODE_ENV=development postcss src/styles/tailwind.css -o src/styles/tailwind-output.css -w",
99 "tailwind:build": "cross-env TAILWIND_MODE=build cross-env NODE_ENV=production postcss src/styles/tailwind.css -o src/styles/tailwind-output.css",
10− "dev": "concurrently \"npm run dev:only\" \"npm run tailwind:watch\"",
11− "build": "npm run tailwind:build && npm run build:only",
10+ "dev": "concurrently \"npm run dev:vite\" \"npm run tailwind:watch\"",
11+ "build": "npm run tailwind:build && npm run build:vite",
1212 "preview": "vite preview",
1313 "check": "svelte-check --tsconfig ./tsconfig.json",
14− "install": "npm run build && ../install.sh "
14+ "_install:glob": "../bin/install.sh -g $GLOBBER_DESK",
15+ "_install:desk": "../bin/install.sh $ASTROLABE_DESK",
16+ "_install:desk:watch": "../bin/install.sh -w $ASTROLABE_DESK",
17+ "install:glob": "dotenv -c local npm run _install:glob",
18+ "install:desk": "dotenv -c local npm run _install:desk",
19+ "install:desk:watch": "dotenv -c local npm run _install:desk:watch",
20+ "release": "npm run build && npm run install:glob",
21+ "_get-glob": "../bin/get_glob.sh $GLOBBER_DESK",
22+ "get-glob": "dotenv -c local npm run _get-glob",
23+ "_commit": "../bin/commit.sh $ASTROLABE_DESK",
24+ "commit": "dotenv -c local npm run _commit"
1525 },
1626 "devDependencies": {
1727 "@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
@@ -20,8 +30,10 @@
2030 "autoprefixer": "^10.4.2",
2131 "concurrently": "^7.0.0",
2232 "cross-env": "^7.0.3",
33+ "dotenv-cli": "^6.0.0",
2334 "postcss-cli": "^9.1.0",
24− "svelte": "^3.44.0",
35+ "sass": "^1.50.0",
36+ "svelte": "^3.48.0",
2537 "svelte-check": "^2.2.7",
2638 "svelte-preprocess": "^4.9.8",
2739 "svelte-spa-router": "^3.2.0",
@@ -31,15 +43,17 @@
3143 "vite": "^2.7.2"
3244 },
3345 "dependencies": {
46+ "@johnhyde/sigil-js": "github:johnhyde/sigil-js",
3447 "@tlon/phonemes-js": "^1.0.0",
3548 "@tlon/sigil-js": "^1.4.5",
3649 "@urbit/api": "^2.1.0",
3750 "@urbit/http-api": "^2.1.0",
3851 "bn.js": "^5.2.0",
39− "i": "^0.3.7",
40− "npm": "^8.6.0",
41− "sass": "^1.50.0",
52+ "graphology": "^0.24.1",
53+ "lodash": "^4.17.21",
54+ "sigma-jh": "^2.4.2",
4255 "svelte-copy-to-clipboard": "^0.2.5",
56+ "svelte-markdown": "^0.2.3",
4357 "tippy.js": "^6.3.7",
4458 "urbit-ob": "^5.0.1"
4559 }
ui/public/android-chrome-192x192.pngnew file

Binary file not shown.

ui/public/android-chrome-512x512.pngnew file

Binary file not shown.

ui/public/apple-touch-icon.pngnew file

Binary file not shown.

ui/public/favicon-16x16.pngnew file

Binary file not shown.

ui/public/favicon-32x32.pngnew file

Binary file not shown.

ui/public/favicon.ico

Binary file not shown.

ui/public/sigil-example.pngnew file

Binary file not shown.

ui/public/site.webmanifestnew file+1
@@ -0,0 +1 @@
1+{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
ui/scraps/tirrel-graph-main.jsnew file+198
@@ -0,0 +1,198 @@
1+// Let's first initialize sigma:
2+//
3+
4+let fetchArray = [];
5+for (let i = 0; i < 256; i++) {
6+ fetchArray.push(
7+ fetch(`./galaxies/${i.toString()}.json`).then(r => r.json())
8+ );
9+}
10+
11+let searchButton = document.getElementById('searchButton');
12+
13+Promise.all(fetchArray).then(values => {
14+ sigma.settings.minEdgeSize = 0;
15+ sigma.settings.maxEdgeSize = 0;
16+ sigma.settings.minNodeSize = 0;
17+ sigma.settings.maxNodeSize = 0;
18+ sigma.settings.zoomMin = 0.00001;
19+ sigma.settings.labelThreshold = 20;
20+ sigma.settings.font = "monospace";
21+
22+ let s = new sigma({
23+ renderer: {
24+ container: document.getElementById('container'),
25+ type: 'webgl'
26+ }
27+ });
28+ let i = 0;
29+
30+ let offsetX = 0;
31+ let offsetY = 0;
32+
33+ let a = 120000000;
34+ let b = 8000000;
35+ let theta = 0;
36+ while (i < values.length) {
37+ offsetX = 0 + (a + b * theta) * Math.cos(theta);
38+ offsetY = 0 + (a + b * theta) * Math.sin(theta);
39+
40+ galaxy(values[i], s, offsetX, offsetY);
41+
42+ theta = 0.12 * (i+1);
43+ i++;
44+ }
45+
46+ s.refresh();
47+
48+ let headerDiv = document.getElementById('header');
49+ headerDiv.style = 'opacity:1;';
50+
51+ let search = document.getElementById('header');
52+ let searchInput = document.getElementById('searchInput');
53+
54+ let searchFunc = () => {
55+ let ob = window['urbit-ob'].default;
56+ let point = s.graph.nodes(searchInput.value);
57+ if (!point) {
58+ return;
59+ }
60+
61+ let ratio = 0.05;
62+ if (ob.clan(searchInput.value) === 'star') {
63+ ratio = 0.018;
64+ } else if (ob.clan(searchInput.value) === 'planet') {
65+ ratio = 0.003;
66+ }
67+
68+ s.cameras['0'].goTo({
69+ x: point['read_cam0:x'],
70+ y: point['read_cam0:y'],
71+ ratio: ratio,
72+ angle: 0
73+ });
74+ };
75+
76+ searchButton.addEventListener('click', searchFunc);
77+ searchInput.addEventListener('keyup', (e) => {
78+ if (e.key === 'Enter') {
79+ searchFunc();
80+ }
81+ });
82+});
83+
84+const galaxy = (data, s, offsetX = 0, offsetY = 0) => {
85+ // Then, let's add some data to display:
86+ let ob = window['urbit-ob'].default;
87+
88+ for (let [key, val] of Object.entries(data)) {
89+ s.graph.addNode({
90+ id: ob.patp(key),
91+ label: ob.patp(key),
92+ size: 4,
93+ color: '#999',
94+ x: 0 + offsetX,
95+ y: 0 + offsetY
96+ });
97+
98+ let numOfStars = Object.entries(val).length;
99+ let starIter = 0;
100+ for (let [starKey, starVal] of Object.entries(val)) {
101+ const circle = 2 * Math.PI;
102+ let line = 40000 * 128;
103+ let starX = 0 + Math.cos(circle * starIter / numOfStars) * line;
104+ let starY = 0 + Math.sin(circle * starIter / numOfStars) * line;
105+
106+ s.graph.addNode({
107+ id: ob.patp(starKey),
108+ label: ob.patp(starKey),
109+ size: 1.5,
110+ color: '#444',
111+ x: starX + offsetX,
112+ y: starY + offsetY
113+ }).addEdge({
114+ id: `e-star${starKey}`,
115+ source: ob.patp(key),
116+ target: ob.patp(starKey),
117+ color: '#444',
118+ size: 0.2
119+ });
120+
121+ let starAngle = Math.atan2(starY, starX);
122+ let numOfPlanets = Object.entries(starVal).length;
123+ let planetIter = 0;
124+
125+ for (let [planetKey, planetVal] of Object.entries(starVal)) {
126+ let planetAngle = starAngle + (Math.PI * 2 * (planetIter / numOfPlanets));
127+
128+ let lineLen = 0;
129+ let lineColor = '#000';
130+ let nodeColor = '#000';
131+
132+ if (planetIter % 4 === 0) {
133+ lineLen = 19000;
134+ lineColor = '#000';
135+ nodeColor = '#000';
136+ } else if (planetIter % 4 === 1) {
137+ lineLen = 16000;
138+ lineColor = '#ccc';
139+ nodeColor = '#ccc';
140+ } else if (planetIter % 4 === 2) {
141+ lineLen = 13000;
142+ lineColor = '#555';
143+ nodeColor = '#555';
144+ } else if (planetIter % 4 === 3) {
145+ lineLen = 16000;
146+ lineColor = '#ccc';
147+ nodeColor = '#ccc';
148+ }
149+
150+ if (numOfStars < 5) {
151+ lineLen = lineLen * 144;
152+ } else if (numOfStars < 7) {
153+ lineLen = lineLen * 128;
154+ } else if (numOfStars < 9) {
155+ lineLen = lineLen * 96;
156+ } else if (numOfStars < 11) {
157+ lineLen = lineLen * 80;
158+ } else if (numOfStars < 13) {
159+ lineLen = lineLen * 64;
160+ } else if (numOfStars < 15) {
161+ lineLen = lineLen * 56;
162+ } else if (numOfStars < 17) {
163+ lineLen = lineLen * 48;
164+ } else if (numOfStars < 19) {
165+ lineLen = lineLen * 40;
166+ } else if (numOfStars < 21) {
167+ lineLen = lineLen * 36;
168+ } else if (numOfStars < 23) {
169+ lineLen = lineLen * 32;
170+ } else {
171+ lineLen = lineLen * 24;
172+ }
173+
174+ let planetX = starX + (lineLen * Math.cos(planetAngle));
175+ let planetY = starY + (lineLen * Math.sin(planetAngle));
176+
177+ s.graph.addNode({
178+ id: ob.patp(planetVal),
179+ label: ob.patp(planetVal),
180+ size: 0.2,
181+ color: nodeColor,
182+ x: planetX + offsetX,
183+ y: planetY + offsetY
184+ }).addEdge({
185+ id: `e-planet${planetVal}`,
186+ source: ob.patp(starKey),
187+ target: ob.patp(planetVal),
188+ size: 0.05,
189+ color: lineColor
190+ });
191+
192+ planetIter++;
193+ }
194+
195+ starIter++;
196+ }
197+ }
198+};
ui/src/App.svelte+65−8
@@ -1,19 +1,76 @@
11<script lang="ts">
22 import Router from 'svelte-spa-router';
3− import Urbit from '@urbit/http-api';
4− import { Charges, ChargeUpdateInitial, scryCharges } from '@urbit/api';
3+ import SigilPage from './routes/SigilPage.svelte';
4+ import HelpPage from './routes/HelpPage.svelte';
55 import Home from './routes/Home.svelte';
6− import ShipViewPage from './routes/ShipViewPage.svelte';
6+ import HelpModal from '@/docs/HelpModal.svelte';
77 import "./styles/styles.scss";
8+ import docs from 'stores/docs';
9+ import keys from 'stores/keys';
10+
11+ // const routes = {
12+ // '/help/:path?': HelpPage,
13+ // // '/:patp?': Home,
14+ // '/ship/:patp?': Home,
15+ // '/search/:search?': Home,
16+ // '*': Home,
17+ // }
818
919 const routes = {
10− // '/': Home,
11− '/:patp?': ShipViewPage,
12− '/ship/:patp?': ShipViewPage,
13− '*': Home,
20+ '/sigil': SigilPage,
21+ '/help/:path?': HelpPage,
22+ // '/:patp?': Home,
23+ // '/ship/:patp?': Home,
24+ // '/search/:search?': Home,
25+ '/:mode?/:arg?': Home,
26+ }
27+
28+ import pageName from './stores/pageName';
29+
30+ $: title = $pageName ? `Astrolabe - ${$pageName}` : 'Astrolabe';
31+
32+ $: {
33+ document.title = title
34+ }
35+
36+ function inputEvent(event) {
37+ if (event.target.tagName == 'INPUT') return true;
38+ if (event.target.tagName == 'TEXTAREA') return true;
39+ return false;
40+ }
41+
42+ function handleKeyDown(event: KeyboardEvent) {
43+ keys.runCallbacks($keys.globalkeydown, event);
44+ if (!inputEvent(event)) {
45+ keys.runCallbacks($keys.keydown, event);
46+ }
47+ }
48+
49+ function handleKeyUp(event: KeyboardEvent) {
50+ keys.runCallbacks($keys.globalkeyup, event);
51+ if (!inputEvent(event)) {
52+ keys.runCallbacks($keys.keyup, event);
53+ }
54+ }
55+
56+ $:{
57+ $keys.keyup.get('?').set('app', () => docs.show(''));
58+ $keys.keyup.get('shift+?').set('app', () => docs.show(''));
59+ $keys.globalkeyup.get('escape').set('app', (event) => {
60+ if (inputEvent(event)) {
61+ event.target.blur();
62+ }
63+ });
1464 }
1565</script>
1666
17−<main>
67+<main class="h-full overflow-y-auto">
68+ <HelpModal />
1869 <Router {routes} />
1970</main>
71+
72+<svelte:head>
73+ <title>{title}</title>
74+</svelte:head>
75+
76+<svelte:body on:keydown={handleKeyDown} on:keyup={handleKeyUp} />
ui/src/actions/doc.tsdeleted−39
@@ -1,39 +0,0 @@
1−import UrbitApi from '@urbit/http-api';
2−const api: UrbitApi = new UrbitApi('');
3−
4−async function getDoc(path) {
5− return api.scry<any>({ app: 'astrolabe', path: `/doc/${path}` });
6−}
7−
8−export default function doc(node, path: string) {
9− // Determine the title to show. We want to prefer
10− // the custom content passed in first, then the
11− // HTML title attribute then the aria-label
12− // in that order.
13− const custom = params.content;
14− const title = node.title;
15− const label = node.getAttribute("aria-label");
16− const content = custom || title || label;
17−
18− // Let's make sure the "aria-label" attribute
19− // is set so our element is accessible:
20− // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute
21− if (!label) node.setAttribute("aria-label", content);
22−
23− // Clear out the HTML title attribute since
24− // we don't want the default behavior of it
25− // showing up on hover.
26− node.title = "";
27−
28− // Support any of the Tippy props by forwarding all "params":
29− // https://atomiks.github.io/tippyjs/v6/all-props/
30− const tip: any = tippy(node, mergeParams(content, params));
31−
32− return {
33− // If the props change, let's update the Tippy instance:
34− update: (newParams) => tip.setProps(mergeParams(content, newParams)),
35−
36− // Clean up the Tippy instance on unmount:
37− destroy: () => tip.destroy(),
38− };
39−};
ui/src/actions/docLinks.tsnew file+26
@@ -0,0 +1,26 @@
1+const docLinkRegex = /\/~\/scry\/docs\/usr\/astrolabe\/([-~._\w\d]+).html/;
2+
3+function convertDocLinks(node, onPathChange) {
4+ const links = node.querySelectorAll('a');
5+ for (let link of links) {
6+ let match = link.href.match(docLinkRegex);
7+ if (match) {
8+ let path = match[1];
9+ link.href="javascript:void(0)";
10+ link.addEventListener('click', () => onPathChange(path));
11+ // const button = document.createElement('button');
12+ // while(link.firstChild) {
13+ // button.appendChild(link.firstChild);
14+ // }
15+ // link.parentNode.replaceChild(button, link);
16+ // debugger;
17+ }
18+ }
19+}
20+
21+export default function docLinks(node, onPathChange: Function) {
22+ convertDocLinks(node, onPathChange)
23+ return {
24+ update: (onPathChange) => convertDocLinks(node, onPathChange),
25+ };
26+};
ui/src/actions/symbolPartClick.tsnew file+27
@@ -0,0 +1,27 @@
1+function listenOnSvgElements(node, onPathChange) {
2+ const parts = node.querySelectorAll('path, circle, line');
3+ for (let part of parts) {
4+ if (part.getAttribute('dataisgeon') === 'true') continue;
5+ if (onPathChange) {
6+ part.onclick = () => {
7+ onPathChange(part.getAttribute('part-key'));
8+ };
9+ } else {
10+ part.onclick = null;
11+ }
12+ }
13+}
14+
15+export default function svgClick(node: HTMLElement, { onPartClick, enabled = true, svgString }) {
16+ if (enabled) listenOnSvgElements(node, onPartClick);
17+
18+ return {
19+ update: ({ onPartClick, enabled = true, svgString }) => {
20+ if (enabled) {
21+ listenOnSvgElements(node, onPartClick);
22+ } else {
23+ listenOnSvgElements(node, undefined);
24+ }
25+ },
26+ };
27+}
ui/src/actions/tooltip.ts+40−8
@@ -1,24 +1,45 @@
11import tippy from 'tippy.js';
2+// import DocLink from '@/docs/DocLink.svelte'; // TODO try to add a link in the tooltip somehow or something, like:
3+// const app = new DocLink({
4+// target: document.getElementBySelector('.tippy')
5+// })
26
37const defaultParams = {
48 theme: 'astrolabe',
9+ delay: [500, 0],
510};
611
7−function getParams(paramsOrContent:any = {}) {
12+function getParams(paramsOrContent:any = {}, overrides = {}) {
13+ let params = paramsOrContent;
814 if (typeof paramsOrContent === 'string') {
9− return {
10− ...defaultParams,
11− content: paramsOrContent,
12− }
15+ params = { content: paramsOrContent };
1316 }
1417 return {
1518 ...defaultParams,
16− ...paramsOrContent,
19+ ...params,
20+ ...overrides,
1721 };
1822}
1923
2024export default function tooltip(node, paramsOrContent: any = {}) {
21− const params = getParams(paramsOrContent);
25+ const onTrigger = () => {
26+ // console.log('triggered');
27+ node.dispatchEvent(new CustomEvent("tooltipTriggered"));
28+ };
29+ const onUntrigger = () => {
30+ // console.log('untriggered');
31+ node.dispatchEvent(new CustomEvent("tooltipUntriggered"));
32+ };
33+ const onClickOutside = (_, e) => {
34+ e.stopPropagation();
35+ };
36+ const listeners = {
37+ onTrigger,
38+ onUntrigger,
39+ onClickOutside,
40+ }
41+
42+ const params = getParams(paramsOrContent, listeners);
2243 const { content } = params;
2344
2445 // Let's make sure the "aria-label" attribute
@@ -30,12 +51,23 @@ export default function tooltip(node, paramsOrContent: any = {}) {
3051 // Support any of the Tippy props by forwarding all "params":
3152 // https://atomiks.github.io/tippyjs/v6/all-props/
3253 const tip: any = tippy(node, params);
54+ const hideTip = (e) => {
55+ if (tip.state.isShown) {
56+ tip.hide();
57+ // e.stopPropagation();
58+ }
59+ }
60+ node.addEventListener('click', hideTip);
61+
3362
3463 return {
3564 // If the props change, let's update the Tippy instance:
3665 update: (newParams) => tip.setProps(getParams(newParams)),
3766
3867 // Clean up the Tippy instance on unmount:
39− destroy: () => tip.destroy(),
68+ destroy: () => {
69+ node.removeEventListener('click', hideTip);
70+ tip.destroy();
71+ }
4072 };
4173};
ui/src/assets/astrolabe-tile.svgnew file+23
@@ -0,0 +1,23 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3+<svg width="440mm" height="440mm" version="1.1" viewBox="-100 -100 440 440" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
4+ <defs>
5+ <linearGradient id="gold">
6+ <stop stop-color="#fcd34d" offset="0"/>
7+ </linearGradient>
8+ <linearGradient id="linearGradient3024" x1="95" x2="105" y1="47.5" y2="47.5" gradientTransform="translate(20,-30)" gradientUnits="userSpaceOnUse" xlink:href="#gold"/>
9+ <linearGradient id="linearGradient3030" x2="200" y1="150" y2="150" gradientTransform="translate(20,-30)" gradientUnits="userSpaceOnUse" xlink:href="#gold"/>
10+ <linearGradient id="linearGradient3036" x1="60" x2="180" y1="170" y2="170" gradientTransform="matrix(1.0909 0 0 1.0909 4.0909 -50.455)" gradientUnits="userSpaceOnUse" xlink:href="#gold"/>
11+ <linearGradient id="linearGradient3066" x1="27.226" x2="161.28" y1="154.82" y2="154.82" gradientTransform="rotate(19 199.64 194.76)" gradientUnits="userSpaceOnUse" xlink:href="#gold"/>
12+ <linearGradient id="linearGradient3072" x1="90" x2="110" y1="150" y2="150" gradientTransform="translate(20,-30)" gradientUnits="userSpaceOnUse" xlink:href="#gold"/>
13+ <linearGradient id="linearGradient4362" x2="240" y1="120" y2="120" gradientTransform="matrix(1.8333 0 0 1.8333 -100 -100)" gradientUnits="userSpaceOnUse">
14+ <stop stop-color="#1f243c" offset="0"/>
15+ </linearGradient>
16+ </defs>
17+ <rect x="-100" y="-100" width="440" height="440" fill="url(#linearGradient4362)"/>
18+ <circle cx="120" cy="120" r="95" fill="none" stroke="url(#linearGradient3030)" stroke-width="10"/>
19+ <circle cx="135" cy="135" r="60" fill="none" stroke="url(#linearGradient3036)" stroke-width="10"/>
20+ <circle cx="120" cy="120" r="10" fill="url(#linearGradient3072)"/>
21+ <path d="m35.978 152.25 140.04-53.755-5.7521 12.92-46.679 17.918-7.1673-18.672-74.686 28.669z" fill="url(#linearGradient3066)"/>
22+ <path d="m120 25v-20" fill="none" stroke="url(#linearGradient3024)" stroke-linecap="round" stroke-width="10"/>
23+</svg>
ui/src/assets/astrolabe.svgnew file+206
@@ -0,0 +1,206 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3+
4+<svg
5+ width="240mm"
6+ height="240mm"
7+ viewBox="0 0 240 240"
8+ version="1.1"
9+ id="svg5"
10+ inkscape:version="1.1.1 (c3084ef, 2021-09-22)"
11+ sodipodi:docname="astrolabe.svg"
12+ inkscape:export-filename="/Users/john/ws/urbit-apps/astrolabe/extras/astrolabe.png"
13+ inkscape:export-xdpi="96"
14+ inkscape:export-ydpi="96"
15+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
16+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
17+ xmlns:xlink="http://www.w3.org/1999/xlink"
18+ xmlns="http://www.w3.org/2000/svg"
19+ xmlns:svg="http://www.w3.org/2000/svg">
20+ <sodipodi:namedview
21+ id="namedview7"
22+ pagecolor="#ffffff"
23+ bordercolor="#999999"
24+ borderopacity="1"
25+ inkscape:pageshadow="0"
26+ inkscape:pageopacity="0"
27+ inkscape:pagecheckerboard="0"
28+ inkscape:document-units="mm"
29+ showgrid="false"
30+ inkscape:zoom="0.4798268"
31+ inkscape:cx="452.24652"
32+ inkscape:cy="416.81707"
33+ inkscape:window-width="1549"
34+ inkscape:window-height="1080"
35+ inkscape:window-x="490"
36+ inkscape:window-y="130"
37+ inkscape:window-maximized="0"
38+ inkscape:current-layer="layer1" />
39+ <defs
40+ id="defs2">
41+ <linearGradient
42+ id="navy"
43+ inkscape:swatch="solid">
44+ <stop
45+ style="stop-color:#1f243c;stop-opacity:1;"
46+ offset="0"
47+ id="stop4358" />
48+ </linearGradient>
49+ <linearGradient
50+ id="linearGradient3070"
51+ inkscape:swatch="solid">
52+ <stop
53+ style="stop-color:#ffff00;stop-opacity:1;"
54+ offset="0"
55+ id="stop3068" />
56+ </linearGradient>
57+ <linearGradient
58+ id="linearGradient3064"
59+ inkscape:swatch="solid">
60+ <stop
61+ style="stop-color:#ff3500;stop-opacity:1;"
62+ offset="0"
63+ id="stop3062" />
64+ </linearGradient>
65+ <linearGradient
66+ id="linearGradient3040"
67+ inkscape:swatch="solid">
68+ <stop
69+ style="stop-color:#fcd34d;stop-opacity:1;"
70+ offset="0"
71+ id="stop3038" />
72+ </linearGradient>
73+ <linearGradient
74+ id="linearGradient3034"
75+ inkscape:swatch="solid">
76+ <stop
77+ style="stop-color:#f2c11c;stop-opacity:1;"
78+ offset="0"
79+ id="stop3032" />
80+ </linearGradient>
81+ <linearGradient
82+ id="linearGradient3028"
83+ inkscape:swatch="solid">
84+ <stop
85+ style="stop-color:#f2e41c;stop-opacity:1;"
86+ offset="0"
87+ id="stop3026" />
88+ </linearGradient>
89+ <linearGradient
90+ id="gold"
91+ inkscape:swatch="solid">
92+ <stop
93+ style="stop-color:#fcd34d;stop-opacity:1;"
94+ offset="0"
95+ id="stop3020" />
96+ </linearGradient>
97+ <linearGradient
98+ inkscape:collect="always"
99+ xlink:href="#gold"
100+ id="linearGradient3024"
101+ x1="95"
102+ y1="47.5"
103+ x2="105"
104+ y2="47.5"
105+ gradientUnits="userSpaceOnUse"
106+ gradientTransform="translate(20,-30)" />
107+ <linearGradient
108+ inkscape:collect="always"
109+ xlink:href="#gold"
110+ id="linearGradient3030"
111+ x1="0"
112+ y1="150"
113+ x2="200"
114+ y2="150"
115+ gradientUnits="userSpaceOnUse"
116+ gradientTransform="translate(20,-30)" />
117+ <linearGradient
118+ inkscape:collect="always"
119+ xlink:href="#gold"
120+ id="linearGradient3036"
121+ x1="60.000027"
122+ y1="170"
123+ x2="179.99998"
124+ y2="170"
125+ gradientUnits="userSpaceOnUse"
126+ gradientTransform="matrix(1.0909095,0,0,1.0909095,4.090855,-50.454621)" />
127+ <linearGradient
128+ inkscape:collect="always"
129+ xlink:href="#gold"
130+ id="linearGradient3066"
131+ x1="27.225779"
132+ y1="154.82091"
133+ x2="161.28355"
134+ y2="154.82091"
135+ gradientUnits="userSpaceOnUse"
136+ gradientTransform="rotate(19,199.63646,194.75765)" />
137+ <linearGradient
138+ inkscape:collect="always"
139+ xlink:href="#gold"
140+ id="linearGradient3072"
141+ x1="90"
142+ y1="150"
143+ x2="110"
144+ y2="150"
145+ gradientUnits="userSpaceOnUse"
146+ gradientTransform="translate(20,-30)" />
147+ <linearGradient
148+ inkscape:collect="always"
149+ xlink:href="#navy"
150+ id="linearGradient4362"
151+ x1="0"
152+ y1="120"
153+ x2="240"
154+ y2="120"
155+ gradientUnits="userSpaceOnUse"
156+ gradientTransform="matrix(1.8333333,0,0,1.8333333,-99.999996,-99.999996)" />
157+ </defs>
158+ <g
159+ inkscape:label="Layer 1"
160+ inkscape:groupmode="layer"
161+ id="layer1">
162+ <rect
163+ style="display:none;fill:url(#linearGradient4362);fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
164+ id="rect4185"
165+ width="440"
166+ height="440"
167+ x="-100"
168+ y="-100"
169+ inkscape:label="bg" />
170+ <circle
171+ style="display:inline;fill:none;fill-rule:evenodd;stroke:url(#linearGradient3030);stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
172+ id="path31"
173+ cx="120"
174+ cy="120"
175+ r="95"
176+ inkscape:label="mater plate" />
177+ <circle
178+ style="display:inline;fill:none;fill-rule:evenodd;stroke:url(#linearGradient3036);stroke-width:9.99995;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
179+ id="circle996"
180+ cx="135"
181+ cy="134.99998"
182+ r="60.000023"
183+ inkscape:label="rete" />
184+ <circle
185+ style="fill:url(#linearGradient3072);fill-opacity:1;stroke:none;stroke-width:9.99999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
186+ id="path1284"
187+ cx="120"
188+ cy="120"
189+ r="10"
190+ inkscape:label="center" />
191+ <path
192+ style="display:inline;fill:url(#linearGradient3066);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
193+ d="m 35.977829,152.25317 140.036991,-53.75521 -5.75214,12.9195 -46.679,17.91834 -7.16733,-18.67158 -74.686466,28.66941 z"
194+ id="path1819"
195+ sodipodi:nodetypes="ccccccc"
196+ inkscape:transform-center-y="5.3755585"
197+ inkscape:transform-center-x="14.003679"
198+ inkscape:label="alidade" />
199+ <path
200+ style="fill:none;stroke:url(#linearGradient3024);stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
201+ d="M 120,25 V 5"
202+ id="path2712"
203+ sodipodi:nodetypes="cc"
204+ inkscape:label="tab" />
205+ </g>
206+</svg>
ui/src/assets/up-arrow.svgnew file+1
@@ -0,0 +1 @@
1+<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g data-name="Layer 2"><g data-name="arrow-ios-upward"><rect width="24" height="24" transform="rotate(180 12 12)" opacity="0"/><path d="M18 15a1 1 0 0 1-.64-.23L12 10.29l-5.37 4.32a1 1 0 0 1-1.41-.15 1 1 0 0 1 .15-1.41l6-4.83a1 1 0 0 1 1.27 0l6 5a1 1 0 0 1 .13 1.41A1 1 0 0 1 18 15z"/></g></g></svg>
ui/src/assets/x.svgnew file+1
@@ -0,0 +1 @@
1+<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g data-name="Layer 2"><g data-name="close"><rect width="24" height="24" transform="rotate(180 12 12)" opacity="0"/><path d="M13.41 12l4.3-4.29a1 1 0 1 0-1.42-1.42L12 10.59l-4.29-4.3a1 1 0 0 0-1.42 1.42l4.3 4.29-4.3 4.29a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0l4.29-4.3 4.29 4.3a1 1 0 0 0 1.42 0 1 1 0 0 0 0-1.42z"/></g></g></svg>
ui/src/components/CollapsibleContent.svelte+4−5
@@ -1,18 +1,17 @@
11<script lang="ts">
2− import { slide } from 'svelte/transition';
3− import { quintOut } from 'svelte/easing';
4−
2+ import { slide } from 'svelte/transition';
53 export let open: boolean = true;
64</script>
75
86<div class="mt-2">
97 <button on:click={() => (open = !open)}>
10− <span class="font-mono">{open ? '▼' : '▶'}</span>
8+ <span class="font-mono inline-block transition duration-150 {open ? 'rotate-90' : ''}">▶</span>
119 &nbsp;
1210 <slot name="title"></slot>
1311 </button>
1412 {#if open}
15− <div class="ml-[22px]" transition:slide="{{duration: 50 }}">
13+ <!-- turns out it's important not to put an await in the content -->
14+ <div class="ml-[22px]" transition:slide|local="{{duration: 150 }}">
1615 <slot name="content"></slot>
1716 </div>
1817 {/if}
ui/src/components/Doc.sveltedeleted−17
@@ -1,17 +0,0 @@
1−<script lang="ts">
2− import store from '../stores/store';
3−
4− export let path:string;
5−</script>
6−
7−<div class="doc">
8− {#await store.getDoc(path)}
9− <h3>Loading page...</h3>
10− {:then docHtml}
11− {@html docHtml}
12− {:catch error}
13− <h1>Oops!</h1>
14− <h2>Couldn't load the doc at /{path}</h2>
15− <p>Please DM ~midlev-mindyr so he can fix this.</p>
16− {/await}
17−</div>
ui/src/components/DocModal.sveltedeleted−9
@@ -1,9 +0,0 @@
1−<script lang="ts">
2− import Doc from './Doc.svelte';
3−
4− export let path:string;
5−</script>
6−
7−<div class="p-8 rounded-lg bg-white">
8− <Doc {path} />
9−</div>
ui/src/components/ExtensionWindow.sveltenew file+25
@@ -0,0 +1,25 @@
1+<script lang="ts">
2+ export let name: string;
3+ export let open = true;
4+ export let halfWidth = false;
5+ $: containerClasses = open ? ('w-full ' + (halfWidth ? 'md:w-1/2' : '')) : 'w-min justify-self-start';
6+ $: boxClasses = open ? 'border-gray-500' : 'border-gray-400 bg-gray-400';
7+ $: buttonClasses = open ? 'text-gray-600' : 'text-white';
8+</script>
9+
10+<div class="p-1 {containerClasses}">
11+ <div class="border rounded-md {boxClasses}" on:click={() => { if (!open) open = true; }}>
12+ <div class="flex flex-wrap">
13+ <button class="px-2 text-sm {buttonClasses}" on:click|stopPropagation={() => open = !open}>
14+ {name}
15+ </button>
16+ {#if open}
17+ <slot name="top-bar"/>
18+ {/if}
19+ </div>
20+ {#if open}
21+ <slot/>
22+ {/if}
23+ </div>
24+</div>
25+
ui/src/components/GoldBadge.sveltedeleted−21
@@ -1,21 +0,0 @@
1−<script lang="ts">
2− import tooltip from "../actions/tooltip";
3− export let title: string = '';
4− export let doc: string = '';
5−
6−</script>
7−{#if title}
8− <span
9− class="inline-block py-0.5 px-2 rounded-md bg-gold"
10− use:tooltip={title}
11− >
12− <slot></slot>
13− </span>
14−{:else}
15− <span
16− class="inline-block py-0.5 px-2 rounded-md bg-gold"
17− >
18− <slot></slot>
19− </span>
20−{/if}
21−
ui/src/components/HomeScreenTiles.sveltenew file+42
@@ -0,0 +1,42 @@
1+<script lang="ts">
2+ import { createEventDispatcher } from 'svelte';
3+ import { link } from 'svelte-spa-router'
4+ import DocLink from './docs/DocLink.svelte';
5+
6+ const dispatch = createEventDispatcher();
7+ function navigate(path) {
8+ dispatch('navigate', path);
9+ }
10+
11+ function convertLinks(html: string): string {
12+ let converted = html;
13+ const externalLinkRegex = /href="http/g;
14+ converted = converted.replace(externalLinkRegex, 'target="_blank" href="http');
15+ return converted;
16+ }
17+</script>
18+
19+<div class="pt-10 max-w-md w-full flex flex-wrap gap-5 justify-center">
20+ <div class="rounded-lg bg-white grow max-w-xs">
21+ <DocLink modal path="astrolabe">
22+ <div class="p-5 text-xl text-center">
23+ About Astrolabe
24+ </div>
25+ </DocLink>
26+ </div>
27+ <div class="rounded-lg bg-white grow max-w-xs">
28+ <DocLink modal path="">
29+ <div class="p-5 text-xl text-center">
30+ About Urbit IDs
31+ </div>
32+ </DocLink>
33+ </div>
34+ <a class="rounded-lg bg-navy border border-gold grow max-w-s" use:link href="/chart">
35+ <p class="p-5 text-xl text-center text-white">
36+ <br/>
37+ Star Chart
38+ <br/>
39+ <br/>
40+ </p>
41+ </a>
42+</div>
ui/src/components/SearchBar.sveltedeleted−59
@@ -1,59 +0,0 @@
1−<script lang="ts">
2− import ValidationProblems from './ValidationProblems.svelte';
3−
4− import { SearchAnalysis, analyzeSearch } from '../lib/id';
5−
6− export let patp: string = undefined;
7− export let searchQuery: RegExp = /~der/;
8− export let analysis: SearchAnalysis = new SearchAnalysis();
9− export let search = '';
10−
11− // const placeholderText = "Enter a @p or non-negative integer. '*' is wildcard.";
12− const placeholderText = "Enter a @p or non-negative integer";
13−
14− $: {
15− // analysis.search = search;
16− analysis = new SearchAnalysis(search);
17− if (analysis.queryIsValid) {
18− searchQuery = analysis.query;
19− } else {
20− searchQuery = undefined;
21− }
22− if (analysis.patpIsValid) {
23− patp = analysis.patp;
24− } else {
25− patp = undefined;
26− }
27− }
28−</script>
29−
30−<!-- <div class="flex justify-center"> -->
31− <div class="relative grow max-w-md rounded-full w-full">
32− <input type="text" class="p-4 py-2 w-full rounded-full"
33− spellcheck="false"
34− placeholder={placeholderText}
35− bind:value={search}
36− autofocus
37− />
38− <button class="absolute right-0 w-10 h-10 rounded-full bg-black transition-opacity opacity-10 hover:opacity-40"></button>
39− </div>
40−<!-- </div> -->
41−<!-- <div class="bg-gray-300 p-2 rounded-lg">
42− <p>
43− text: {search}
44− </p>
45− <p>
46− query: {searchQuery}
47− </p>
48−</div> -->
49−<!-- {#if search !== '' && analysis && analysis.queryProblems.length > 0}
50− <div class="flex justify-center w-full">
51− <ValidationProblems type="Query Problems" problems={analysis.queryProblems}></ValidationProblems>
52− </div>
53−{/if} -->
54−
55−<!-- {#if search !== '' && analysis && analysis.patpProblems.length > 0}
56− <div class="flex justify-center">
57− <ValidationProblems type="ID Problems" problems={analysis.patpProblems}></ValidationProblems>
58− </div>
59−{/if} -->
ui/src/components/SearchResults.sveltedeleted−68
@@ -1,68 +0,0 @@
1−<script lang="ts">
2− import { Groups, Rolodex } from '@urbit/api';
3− import store from '../stores/store';
4− import ShipListing from './ShipListing.svelte';
5− import SearchResultNavButtons from './SearchResultNavButtons.svelte';
6− import ShipView from './ShipView.svelte';
7− export let searchQuery: RegExp;
8− export let patp: string;
9− let contactsList = [];
10− let selectedShipIndex: number;
11−
12− $: {
13− if (!patp) {
14− store.search(searchQuery)
15− }
16− // if (searchQuery) {
17− // store.search(searchQuery)
18− // } else {
19− // store.reset();
20− // }
21− }
22− $: {
23− contactsList = Object.entries($store?.contacts).map(([patp, ship]) => {
24− return {
25− ...ship,
26− patp,
27− };
28− });
29− if (contactsList.length === 1) {
30− selectedShipIndex = 0;
31− } else {
32− selectedShipIndex = null;
33− }
34− }
35− $: selectedShip = contactsList[selectedShipIndex]
36−
37− function updateIndex(e) {
38− selectedShipIndex = e.detail.index;
39− }
40−</script>
41−
42−<!-- should actually switch on whether field is empty -->
43−<!-- searchQuery is undefined when query is invalid -->
44−<!-- {#if searchQuery === undefined}
45− <p class="p-6 rounded-lg bg-white">
46− Hello, ~{window.ship}, would you like to search?
47− </p>
48−{/if} -->
49−{#if patp}
50− <ShipView {patp} />
51−{:else if selectedShip}
52− {#if contactsList.length > 1}
53− <SearchResultNavButtons
54− index={selectedShipIndex}
55− totalResults={contactsList.length}
56− on:updateIndex={updateIndex}
57− />
58− {/if}
59− <ShipView patp={selectedShip.patp} />
60−{:else}
61− <div class="flex justify-center">
62− <div class="max-w-md w-full rounded-lg bg-white">
63− {#each contactsList as contact, i (contact.patp)}
64− <ShipListing ship={contact} on:click={() => selectedShipIndex = i}/>
65− {/each}
66− </div>
67− </div>
68−{/if}
ui/src/components/ShipListing.svelte+37−11
@@ -1,16 +1,42 @@
11<script lang="ts">
2− import Sigil from "./Sigil.svelte";
2+
3+ import Sigil from "@/common/Sigil.svelte";
4+ import PalStatusIndicator from '@/pals/PalStatusIndicator.svelte';
5+ import { push } from 'svelte-spa-router'
6+ import { normalizeId } from 'lib/id';
7+ import { linkToShip as generateLinkToShip } from 'lib/link';
8+ import { getPalStatus } from 'lib/pals';
9+ import store from 'stores/store';
310 export let ship: any;
11+ export let linkToShip: boolean = false;
12+ export let differentiateContacts = false;
13+
14+ $: patp = normalizeId(ship.patp);
15+ $: contact = $store.contacts[ship.patp];
16+ $: borderClass = differentiateContacts ? (
17+ 'border-l-8 ' + (contact ? 'border-gold' : 'border-gray-300')
18+ ) : '';
19+
20+ function handleClick() {
21+ if (linkToShip) {
22+ push(generateLinkToShip(patp));
23+ }
24+ }
425</script>
526
6−<div class="flex flex-wrap p-4 border-b last:border-none items-center"
7− on:click
8− >
9− <Sigil patp={ship.patp} size={48} />
10− <!-- {#if ship.avatar}
11− <img src={ship.avatar} class="h-12 w-12 mr-4" />
12− {/if} -->
13− <p class="ml-4 break-words" >
14− {ship.patp}<br/>{ship.nickname ? `(${ship.nickname})` : ''}
15− </p>
27+<div class="hover:bg-gray-200 {borderClass} cursor-pointer"
28+on:click={handleClick}
29+on:click
30+>
31+ <div class="flex p-4 items-center gap-x-4">
32+ <Sigil {patp} size={48} useNew noShrink />
33+ <p class="break-words grow">
34+ <span class="align-middle mr-1">
35+ {patp}
36+ </span>
37+ <PalStatusIndicator status={getPalStatus($store.pals, patp)} class="inline" />
38+ <br/>
39+ {contact?.nickname ? `(${contact.nickname})` : ''}
40+ </p>
41+ </div>
1642</div>
ui/src/components/ShipListings.sveltenew file+19
@@ -0,0 +1,19 @@
1+<script lang="ts">
2+ import { createEventDispatcher } from 'svelte';
3+ import ShipListing from '@/ShipListing.svelte';
4+ const dispatch = createEventDispatcher();
5+
6+ export let ships = [];
7+ export let linkToShips = false;
8+ export let differentiateContacts = false;
9+
10+ function onClick(index) {
11+ dispatch('click', index);
12+ }
13+</script>
14+
15+<div class="divide-y">
16+ {#each ships as ship, i (ship.patp)}
17+ <ShipListing {ship} on:click={() => onClick(i)} linkToShip={linkToShips} {differentiateContacts} />
18+ {/each}
19+</div>
ui/src/components/ShipView.sveltedeleted−262
@@ -1,262 +0,0 @@
1−<script lang="ts">
2−
3− import type { Scry } from '@urbit/http-api';
4− import UrbitApi from '@urbit/http-api';
5− import { settings } from '@urbit/api';
6− import { clan, sein, patp2dec } from 'urbit-ob';
7−
8− import { cite, normalizeId } from '../lib/id';
9− import tooltip from "../actions/tooltip";
10− import Sigil from "./Sigil.svelte";
11− import GoldBadge from './GoldBadge.svelte';
12− import ShipLink from './ShipLink.svelte';
13− import EthAddressLink from './EthAddressLink.svelte';
14− import CollapsibleContent from './CollapsibleContent.svelte';
15−
16− export let patp: string;
17−
18− let parentChain: any[];
19− let rawPointInfoPromise: any;
20− let rawPointInfo: any = {};
21− let pointInfo: any = {};
22− const api: UrbitApi = new UrbitApi('');
23− const spawnStatusOptions = {
24− unspawned: {
25− text: 'unspawned',
26− tooltip: 'This point has not yet been spawned by its parent',
27− },
28− locked: {
29− text: 'locked',
30− tooltip: 'This point is currently locked in a Linear Release Contract',
31− },
32− spawned: {
33− text: 'spawned',
34− tooltip: `This point has been spawned`,
35− },
36− spawnedNoKeys: {
37− text: 'spawned (no keys set)',
38− tooltip: 'This point has been spawned, but no keys have been set',
39− },
40− }
41− const layerOptions = {
42− l1: {
43− text: 'on layer 1',
44− tooltip: 'This point is secured as an NFT on the Ethereum blockchain',
45− },
46− l2: {
47− text: 'on layer 2',
48− tooltip: `This point is secured by Urbit's "Layer 2" solution`,
49− },
50− spawn: {
51− text: 'spawns on layer 2',
52− tooltip: 'This point lives on layer 1, but it spawns new points on layer 2',
53− },
54− }
55−
56− $: shipClass = clan(patp);
57− $: azPoint = ['galaxy', 'star', 'planet'].includes(shipClass);
58− $: canSpawnPoints = ['galaxy', 'star'].includes(shipClass);
59− $: {
60− let parents = [patp];
61− let galaxyFound = false;
62− let count = 10;
63− while (!galaxyFound && count > 0) {
64− count--;
65− if (count == 0) {
66− throw new Error("You've got an infinite loop in building the parent chain");
67− }
68− let firstItem = parents[0];
69− if (clan(firstItem) == 'galaxy') {
70− galaxyFound = true;
71− } else {
72− parents.unshift(sein(firstItem))
73− }
74− }
75− parents.pop();
76− parentChain = parents;
77− }
78− $: {
79− rawPointInfo = {};
80− if (azPoint) {
81− rawPointInfoPromise = api.scry<any>({ app: 'astrolabe', path: `/point/${patp}` });
82− rawPointInfoPromise.then((info) => {
83− rawPointInfo = info;
84− });
85− }
86− }
87− $: {
88− pointInfo = {};
89− let spawnStatus: any, layer: any, life: number, rift: number;
90− let keysSet = false;
91− if (!azPoint) {
92−
93− } else if (rawPointInfo.point) {
94− const { point } = rawPointInfo;
95− life = point.net.keys.life;
96− rift = point.net.rift;
97− if (life > 0) {
98− keysSet = true;
99− }
100−
101− pointInfo.proxies = point.own;
102− const { dominion } = point;
103− layer = layerOptions[dominion];
104−
105− if (pointInfo.proxies.owner.address === '0x86cd9cd0992f04231751e3761de45cecea5d1801') {
106− spawnStatus = spawnStatusOptions.locked;
107− } else if (keysSet) {
108− spawnStatus = spawnStatusOptions.spawned;
109− } else {
110− spawnStatus = spawnStatusOptions.spawnedNoKeys;
111− }
112− const { sponsor } = point.net;
113− if (sponsor.has) {
114− pointInfo.sponsor = normalizeId(sponsor.who);
115− }
116− } else {
117− layer = undefined;
118− spawnStatus = spawnStatusOptions.unspawned;
119− life = 0;
120− rift = 0;
121− }
122− pointInfo = {
123− ...pointInfo,
124− layer,
125− spawnStatus,
126− keysSet,
127− life,
128− rift,
129− };
130− }
131−</script>
132−
133−<div class="p-8 max-w-md w-full rounded-lg bg-white flex flex-col md:max-w-2xl">
134− <div class="flex flex-col items-center space-y-4 md:flex-row md:items-start md:space-x-8 md:space-y-0">
135− <div class="w-full max-w-[256px] md:min-w-[256px] flex-shrink-0">
136− <Sigil patp={patp} size={256} />
137− </div>
138− <div class="grow w-full min-w-0">
139− <h2 class="text-2xl text-center">{cite(patp)}</h2>
140− {#if (!azPoint)}
141− <h3 class="text-lg text-center text-gray-700">{patp}</h3>
142− {/if}
143− <h4 class="text-center text-gray-700 break-words" use:tooltip={"The integer representation of this ID"}>
144− {patp2dec(patp)}
145− </h4>
146− <div class="w-full text-center space-y-1.5 -mt-1.5">
147− <span></span>
148− <GoldBadge title={"it's a " + shipClass}>{shipClass}</GoldBadge>
149− {#if azPoint}
150− <GoldBadge title={pointInfo.spawnStatus.tooltip}>{pointInfo.spawnStatus.text}</GoldBadge>
151− {#if pointInfo.layer}
152− <GoldBadge title={pointInfo.layer.tooltip}>{pointInfo.layer.text}</GoldBadge>
153− {/if}
154− {:else if (shipClass === 'moon')}
155− <span>of</span>
156− <ShipLink patp={parentChain.at(-1)}></ShipLink>
157− {:else if (shipClass === 'comet')}
158− <span>under</span>
159− <ShipLink patp={parentChain.at(-1)}></ShipLink>
160− {/if}
161− </div>
162− <div class="mt-4 w-full break-words">
163− {#if parentChain.length > 0}
164− <p>
165− {parentChain.length === 1 ? 'Parent:' : 'Parent Chain:'}
166− {#each parentChain as parent, index}
167− {#if index > 0}{' > '}{/if}
168− <ShipLink patp={parent}></ShipLink>
169− {/each}
170− </p>
171− {/if}
172− {#if azPoint}
173− <CollapsibleContent>
174− <b slot="title">Azimuth Details</b>
175− <div slot="content">
176− {#await rawPointInfoPromise}
177− Loading Azimuth info...
178− {:then value}
179− {#if shipClass !== 'galaxy'}
180− <p>
181− {#if pointInfo.sponsor && shipClass !== 'galaxy'}
182− Sponsor:
183− <ShipLink patp={pointInfo.sponsor}></ShipLink>
184− {:else}
185− Unsponsored
186− {/if}
187− </p>
188− {/if}
189− <p>
190− <span use:tooltip={"Number of times this ship's keys have been set. Must be at least 1 to use the network."}>
191− Key Revision:
192− {pointInfo.life}
193− </span>
194− </p>
195− <p>
196− <span use:tooltip={"Number of times this ship has breached."}>
197− Continuity:
198− {pointInfo.rift}
199− </span>
200− </p>
201− {#if pointInfo.proxies}
202− <p>
203− <span>
204− Owner:
205− <EthAddressLink address={pointInfo.proxies.owner.address} />
206− </span>
207− </p>
208− <p>
209− <span>
210− Management Proxy:
211− <EthAddressLink address={pointInfo.proxies['management-proxy'].address}>
212− <span class="text-gray-700">not set</span>
213− </EthAddressLink>
214− </span>
215− </p>
216− <p>
217− <span>
218− Spawn Proxy:
219− <EthAddressLink address={pointInfo.proxies['spawn-proxy'].address}>
220− <span class="text-gray-700">not set</span>
221− </EthAddressLink>
222− </span>
223− </p>
224− <p>
225− <span>
226− Transfer Proxy:
227− <EthAddressLink address={pointInfo.proxies['transfer-proxy'].address}>
228− <span class="text-gray-700">not set</span>
229− </EthAddressLink>
230− </span>
231− </p>
232− {#if shipClass === 'galaxy'}
233− <p>
234− <span>
235− Voting Proxy:
236− <EthAddressLink address={pointInfo.proxies['voting-proxy'].address}>
237− [not set]
238− </EthAddressLink>
239− </span>
240− </p>
241− {/if}
242− {/if}
243−
244− <!-- {#if value && value.point}
245− <pre class="text-sm overflow-scroll">
246− Raw Info:{JSON.stringify(rawPointInfo, null, 2)}
247− </pre>
248− {/if} -->
249− {/await}
250− </div>
251− </CollapsibleContent>
252− {/if}
253− </div>
254− </div>
255− </div>
256− {#if canSpawnPoints}
257− <div>
258− <h3 class="text-lg">Spawned Points</h3>
259− <span class="text-green-600">// TODO</span>
260− </div>
261− {/if}
262−</div>
ui/src/components/StarChart.sveltenew file+233
@@ -0,0 +1,233 @@
1+<script lang="ts">
2+ import LoadingSpinner from '@/common/LoadingSpinner.svelte';
3+
4+ import { push } from 'svelte-spa-router';
5+ import { onDestroy } from 'svelte';
6+
7+ import Sigma from 'sigma-jh';
8+ import Graph from 'graphology';
9+
10+ import { clan } from 'urbit-ob';
11+ import DocLink from './docs/DocLink.svelte';
12+ import store from 'stores/store';
13+ import keys from 'stores/keys';
14+ import { parseChartData, populateGraph } from 'lib/graph';
15+ import { getChartData } from 'lib/api';
16+ import { linkToShip } from 'lib/link';
17+
18+ import InlineSelect from './buttons/InlineSelect.svelte';
19+
20+ export let patp: string;
21+ let s;
22+ let g = new Graph();
23+ let highlightedPatp;
24+
25+ let firstRender = true;
26+ let mouseDown = false;
27+ let isDragging = false;
28+ let stoppedDragging = Date.now();
29+
30+ function sigma(container: HTMLElement, params: any = {}) {
31+ try {
32+ window['s'] = s = new Sigma(g, container, {
33+ renderLabels: false,
34+ // hideEdgesOnMove: true,
35+ allowInvalidContainer: true,
36+ // labelColor: { color: WHITE },
37+ labelFont: 'monospace',
38+ labelRenderedSizeThreshold: 2.2,
39+ zIndex: true,
40+ maxCameraRatio: 10,
41+ });
42+
43+ s.on('clickNode', ({ node }) => {
44+ if (!isDragging && 100 < Date.now() - stoppedDragging) {
45+ push(linkToShip(node));
46+ }
47+ });
48+ s.on('afterRender', () => {
49+ if (firstRender) {
50+ firstRender = false;
51+ searchFunc();
52+ }
53+ });
54+ const mc = s.getMouseCaptor();
55+ mc.on("mousedown", () => {
56+ mouseDown = true;
57+ });
58+ mc.on('mousemove', () => {
59+ if (mouseDown) {
60+ isDragging = true;
61+ }
62+ });
63+ mc.on('mouseup', () => {
64+ if (!isDragging) {
65+ clearHighlight();
66+ } else {
67+ stoppedDragging = Date.now();
68+ }
69+ mouseDown = false;
70+ isDragging = false;
71+ })
72+
73+ } catch(e) {
74+ console.error('error in initializing sigma:', e);
75+ if (!params.retried) {
76+ setTimeout(() => sigma(container, { retried: true }), 50);
77+ }
78+ }
79+
80+ return {
81+ destroy() {
82+ s?.kill();
83+ }
84+ }
85+ }
86+
87+ let chartDataPromise: any;
88+ let rawChartData: any = null;
89+ $: {
90+ rawChartData = null;
91+ chartDataPromise = getChartData();
92+ chartDataPromise.then((info) => {
93+ rawChartData = info;
94+ }).catch((error) => {
95+ rawChartData = { error };
96+ });
97+ }
98+ $: parsedChartData = parseChartData(rawChartData, filterSet);
99+ $: [parsedChartData, childKey], populateGraph(g, parsedChartData, childKey, () => {
100+ searchFunc();
101+ });
102+
103+ function clearHighlight() {
104+ const id = highlightedPatp;
105+ if (id) {
106+ setTimeout(() => {
107+ s.graph.removeNodeAttribute(id, 'highlighted');
108+ if (id == highlightedPatp)
109+ highlightedPatp = null;
110+ });
111+ }
112+ }
113+
114+ function searchFunc() {
115+ // console.log('searching for ' + patp);
116+ if (!s) return;
117+ if (highlightedPatp !== patp) clearHighlight();
118+ if (!patp) return;
119+ let point = s.getNodeDisplayData(patp);
120+ if (!point) return;
121+ s.graph.setNodeAttribute(patp, 'highlighted', true);
122+ highlightedPatp = patp;
123+
124+ let ratio = 0.03;
125+ if (clan(patp) === 'star') {
126+ ratio = 0.008;
127+ } else if (clan(patp) === 'planet') {
128+ ratio = 0.0005;
129+ }
130+
131+ s.camera.animate({
132+ x: point.x,
133+ y: point.y,
134+ ratio: ratio,
135+ angle: 0
136+ }, {
137+ duration: 500,
138+ });
139+ };
140+
141+ $: [s, patp], searchFunc();
142+
143+ let helpBoxExpanded = false;
144+ let helpBoxClasses = '';
145+ $: {
146+ helpBoxClasses = helpBoxExpanded ?
147+ "w-full" :
148+ "border-r";
149+ }
150+ let childKey: ('sponsees' | 'children') = 'sponsees';
151+ let filterSet: Set<string> = null;
152+ $: peersSet = new Set($store.peers);
153+ $: palsSet = new Set(Object.keys($store.pals.outgoing));
154+
155+ function closeChart() {
156+ push('/');
157+ }
158+
159+ $: {
160+ $keys.keyup.get('escape').set('starChart', closeChart);
161+ }
162+
163+ onDestroy(() => {
164+ $keys.keyup.get('escape').delete('starChart');
165+ });
166+</script>
167+
168+<div class="border border-gold bg-navy w-full grow flex flex-col relative">
169+ <div class="flex flex-wrap absolute {helpBoxClasses} border-b border-gold bg-navy text-white z-20 cursor-pointer justify-items-center px-2 py-1 gap-4"
170+ on:click={() => helpBoxExpanded = !helpBoxExpanded }>
171+ {#if helpBoxExpanded}
172+ <DocLink modal path="astrolabe">
173+ <div class="text-center justify-self-start">
174+ About Astrolabe
175+ </div>
176+ </DocLink>
177+ <div class="flex flex-wrap items-center gap-2">
178+ <div class="w-3 h-3 rounded-full bg-white"></div>
179+ Galaxy
180+ </div>
181+ <div class="flex flex-wrap items-center gap-2">
182+ <div class="w-3 h-3 rounded-full bg-gold"></div>
183+ Star
184+ </div>
185+ <div class="flex flex-wrap items-center gap-2">
186+ <div class="w-3 h-3 rounded-full bg-l1-blue"></div>
187+ Planet (L1)
188+ </div>
189+ <div class="flex flex-wrap items-center gap-2">
190+ <div class="w-3 h-3 rounded-full bg-l2-green"></div>
191+ Planet (L2)
192+ </div>
193+ {#if s.nodeDataCache['~' + window.ship]}
194+ <div class="flex flex-wrap items-center gap-2">
195+ <div class="w-3 h-3 rounded-full bg-you"></div>
196+ You
197+ </div>
198+ {/if}
199+ {:else}
200+ ?
201+ {/if}
202+ </div>
203+ <div class="flex flex-wrap absolute right-0 border-l border-b border-gold bg-navy text-white z-10 cursor-pointer justify-center px-2 py-1 gap-4"
204+ on:click={() => push('/') }>
205+ X
206+ </div>
207+ <div class="flex absolute -bottom-2 inset-x-0 text-white z-10 2xs:-bottom-3.5">
208+ <!-- <div class="ml-8 px-4 py-1 flex gap-x-1 items-center text-white"> -->
209+ <!-- <span>Arrange by</span> -->
210+ <InlineSelect bind:value={childKey}
211+ options={[
212+ ['Sponsors', 'sponsees'],
213+ ['Parents', 'children']
214+ ]}
215+ ></InlineSelect>
216+ <InlineSelect bind:value={filterSet}
217+ options={[
218+ ['All', null],
219+ ['Peers', peersSet],
220+ ['Pals', palsSet],
221+ ]}
222+ ></InlineSelect>
223+ <!-- </div> -->
224+ </div>
225+ {#await chartDataPromise}
226+ <div class="flex items-center justify-center absolute inset-0">
227+ <LoadingSpinner/>
228+ </div>
229+ {/await}
230+ <div class="grow flex">
231+ <div class="w-full min-h-[20px]" use:sigma></div>
232+ </div>
233+</div>
ui/src/components/ValidationProblems.svelte+3−1
@@ -1,4 +1,6 @@
11<script lang="ts">
2+ import DocLink from './docs/DocLink.svelte';
3+
24 export let problems: Array<string> = [];
35 export let type: string = undefined;
46</script>
@@ -15,7 +17,7 @@
1517 {/each}
1618 <p>
1719 <!-- TODO: add link to doc -->
18− You can read more here.
20+ You can <DocLink modal path="patpee">read more here.</DocLink>
1921 </p>
2022</div>
2123
ui/src/components/buttons/CloseButton.sveltenew file+4
@@ -0,0 +1,4 @@
1+<button on:click class="relative w-7 h-7">
2+ <div class="absolute -mt-0.5 h-1 w-full bg-navy rounded rotate-45" />
3+ <div class="absolute -mt-0.5 h-1 w-full bg-navy rounded -rotate-45" />
4+</button>
ui/src/components/buttons/Hamburger.sveltenew file+5
@@ -0,0 +1,5 @@
1+<button on:click class="w-7 space-y-1 p-1">
2+ <div class="h-1 w-full bg-navy rounded" />
3+ <div class="h-1 w-full bg-navy rounded" />
4+ <div class="h-1 w-full bg-navy rounded" />
5+</button>
ui/src/components/buttons/InlineSelect.sveltenew file+16
@@ -0,0 +1,16 @@
1+<script lang="ts">
2+ export let options: [string, any][];
3+ export let value: any;
4+ export let borderClass = "border-gold";
5+ export let onClass = "bg-navy";
6+ export let offClass = "bg-white";
7+</script>
8+
9+<div class="flex mx-auto border {borderClass} rounded divide-x divide-gold bg-navy">
10+ {#each options as option}
11+ <div class="px-1.5 cursor-pointer" class:text-gray-400={value !== option[1]} on:click={() => value = option[1]}>
12+ {option[0]}
13+ </div>
14+ {/each}
15+</div>
16+
ui/src/components/buttons/ToggleButton.sveltenew file+11
@@ -0,0 +1,11 @@
1+<script lang="ts">
2+ export let on: boolean = true;
3+ export let borderClass = "border-navy";
4+ export let onClass = "bg-navy";
5+ export let offClass = "bg-white";
6+</script>
7+
8+<button on:click
9+ class={`w-4 h-4 rounded-full border ${borderClass} ${on ? onClass : offClass}`}
10+/>
11+
ui/src/components/common/ChartLink.sveltenew file+11
@@ -0,0 +1,11 @@
1+<script lang="ts">
2+ import { link } from 'svelte-spa-router'
3+ import { linkToChart } from 'lib/link';
4+
5+ export let patp = null;
6+</script>
7+
8+<a href={linkToChart(patp)} use:link
9+ class="bg-navy text-white px-2 py-1 rounded no-underline">
10+ <slot/>
11+</a>
ui/src/components/EthAddressLink.svelte → ui/src/components/common/EthAddressLink.svelterenamed+11−4
@@ -1,9 +1,14 @@
11<script lang="ts">
2− import CopyToClipboard from "svelte-copy-to-clipboard";
3− import tooltip from "../actions/tooltip";
2+ import CopyToClipboard from 'svelte-copy-to-clipboard';
3+ import tooltip from 'actions/tooltip';
4+
5+ let overrideText = null;
46
57 const handleSuccessfullyCopied = (e) => {
6− // alert(`successfully copied to clipboard! ${e}`);
8+ overrideText = 'Copied!';
9+ setTimeout(() => {
10+ overrideText = null;
11+ }, 2000);
712 }
813
914 const handleFailedCopy = () => {
@@ -17,7 +22,9 @@
1722
1823{#if address}
1924 <span use:tooltip={address}>
20− <a href={`https://etherscan.io/address/${address}`} target="_blank">{abbrevAddress}</a>
25+ <a href={`https://etherscan.io/address/${address}`} target="_blank">
26+ {overrideText || abbrevAddress}
27+ </a>
2128
2229 <CopyToClipboard text={address} on:copy={handleSuccessfullyCopied} on:fail={handleFailedCopy} let:copy>
2330 <button on:click={copy} class="ml-1 text-3xl align-sub leading-4">⎘</button>
ui/src/components/common/GoldBadge.sveltenew file+10
@@ -0,0 +1,10 @@
1+<script lang="ts">
2+ import TooltipAndDocLink from "./TooltipAndDocLink.svelte";
3+ export let title: string = '';
4+ export let doc: string = '';
5+
6+</script>
7+
8+<TooltipAndDocLink text={title} {doc} class="inline-block py-0.5 px-2 rounded-md bg-gold">
9+ <slot></slot>
10+</TooltipAndDocLink>
ui/src/components/Sigil.svelte → ui/src/components/common/Legil.svelterenamed+16−7
@@ -1,11 +1,15 @@
11<script lang="ts">
22 import { clan } from 'urbit-ob';
3− import { sigil, stringRenderer } from '@tlon/sigil-js';
4− import moonPng from '../assets/moon.png';
5− import cometSvg from '../assets/comet.svg';
3+ import { legil, stringRenderer } from '@johnhyde/legil-js';
4+ import { sigilScalingFunction } from 'lib/sigil';
5+ import moonPng from 'assets/moon.png';
6+ import cometSvg from 'assets/comet.svg';
67
78 export let patp: string;
89 export let size: number;
10+ export let fgColor: string = 'white';
11+ export let bgColor: string = 'black';
12+ export let altBgColor: string = undefined;
913 let svgString: any;
1014 let imgSrc: any;
1115
@@ -13,13 +17,19 @@
1317 $: displaySigil = ['galaxy', 'star', 'planet'].includes(shipClass);
1418 $: {
1519 if (displaySigil) {
16− const svgAST = sigil({
20+ let svgAST;
21+ svgAST = legil({
1722 patp: patp,
1823 size,
19− colors: ['black', 'white'],
24+ colors: [bgColor, fgColor],
25+ autoScaleStrokes: true,
26+ strokeScalingFunctionV2: sigilScalingFunction,
2027 });
2128 svgAST.attributes.preserveAspectRatio = 'xMidYMin slice';
2229 svgString = stringRenderer(svgAST);
30+ if (altBgColor) {
31+ svgString = svgString.replace(/rect fill="[^"]+"/, `rect fill="${altBgColor}"`);
32+ }
2333 } else if (shipClass === 'moon') {
2434 imgSrc = moonPng;
2535 } else {
@@ -28,8 +38,7 @@
2838 }
2939</script>
3040
31−<!-- <div style="height: {size}px; width: {size}px;" > -->
32−<div>
41+<div class="grow" style:max-width="{size}px">
3342 {#if displaySigil}
3443 {@html svgString}
3544 {:else}
ui/src/components/common/LoadingSpinner.sveltenew file+8
@@ -0,0 +1,8 @@
1+<script lang="ts">
2+ export let spinnerClass = "text-white";
3+</script>
4+
5+<svg class="animate-spin h-5 w-5 mx-auto {spinnerClass}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
6+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
7+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
8+</svg>
ui/src/components/ShipLink.svelte → ui/src/components/common/ShipLink.svelterenamed+2−2
@@ -1,7 +1,7 @@
11<script lang="ts">
22 import { link } from 'svelte-spa-router'
3− import { cite, normalizeId } from '../lib/id';
4− import { linkToShip } from '../lib/link';
3+ import { cite, normalizeId } from 'lib/id';
4+ import { linkToShip } from 'lib/link';
55 export let patp: string;
66 $: normalizedId = normalizeId(patp);
77</script>
ui/src/components/common/Sigil.sveltenew file+65
@@ -0,0 +1,65 @@
1+<script lang="ts">
2+ import { clan } from 'urbit-ob';
3+ // import { sigil as sigil1, stringRenderer as sr1 } from '@tlon/sigil-js';
4+ import { sigil as sigil2, stringRenderer as sr2 } from '@johnhyde/sigil-js';
5+ import { sigilScalingFunction, crowdedSigilScalingFunction } from 'lib/sigil';
6+ import moonPng from 'assets/moon.png';
7+ import cometSvg from 'assets/comet.svg';
8+
9+ export let patp: string;
10+ export let size: number;
11+ export let useNew: boolean = false;
12+ export let fgColor: string = 'white';
13+ export let bgColor: string = 'black';
14+ export let altBgColor: string = undefined;
15+ export let noShrink: boolean = false;
16+ let svgString: any;
17+ let imgSrc: any;
18+
19+ $: noShrinkClasses = noShrink ? 'shrink-0' : '';
20+ $: noShrinkWidth = noShrink ? size+'px' : 'initial';
21+
22+ $: shipClass = clan(patp);
23+ $: crowded = ['comet', 'moon'].includes(shipClass);
24+ $: {
25+ // if (displaySigil) {
26+ // let sigil = sigil1;
27+ // let sr = sr1;
28+ // let svgAST;
29+ // if (useNew) {
30+ let sigil = sigil2;
31+ let sr = sr2;
32+ let svgAST = sigil({
33+ patp: patp,
34+ size,
35+ colors: [bgColor, fgColor],
36+ autoScaleStrokes: true,
37+ strokeScalingFunctionV2: crowded ? crowdedSigilScalingFunction : sigilScalingFunction,
38+ });
39+ // } else {
40+ // svgAST = sigil({
41+ // patp: patp,
42+ // size,
43+ // colors: [bgColor, fgColor],
44+ // });
45+ // }
46+ svgAST.attributes.preserveAspectRatio = 'xMidYMin slice';
47+ svgString = sr(svgAST);
48+ if (altBgColor) {
49+ svgString = svgString.replace(/rect fill="[^"]+"/, `rect fill="${altBgColor}"`);
50+ }
51+ // } else if (shipClass === 'moon') {
52+ // imgSrc = moonPng;
53+ // } else {
54+ // imgSrc = cometSvg;
55+ // }
56+ }
57+</script>
58+
59+<div class="grow {noShrinkClasses}" style:max-width="{size}px" style:width={noShrinkWidth}>
60+ <!-- {#if displaySigil} -->
61+ {@html svgString}
62+ <!-- {:else}
63+ <img src={imgSrc} alt={shipClass} class="mx-auto" />
64+ {/if} -->
65+</div>
ui/src/components/common/Tooltip.sveltenew file+37
@@ -0,0 +1,37 @@
1+<script lang="ts">
2+ import tooltip from 'actions/tooltip';
3+ export let text: string = '';
4+ let className: string = '';
5+ export { className as class };
6+ export let enabled: boolean = true;
7+ let tooltipActive: boolean = false;
8+
9+ let timer;
10+
11+ const debounce = v => {
12+ clearTimeout(timer);
13+ timer = setTimeout(() => {
14+ tooltipActive = v;
15+ }, 50);
16+ }
17+
18+ function onTrigger() {
19+ debounce(true);
20+ }
21+
22+ function onUntrigger() {
23+ debounce(false);
24+ }
25+
26+</script>
27+
28+{#if enabled}
29+ <div use:tooltip={text} on:tooltipTriggered={onTrigger} on:tooltipUntriggered={onUntrigger} class={className}>
30+ <slot {tooltipActive} />
31+ </div>
32+{:else}
33+ <div class={className}>
34+ <slot tooltipActive={false} />
35+ </div>
36+{/if}
37+
ui/src/components/common/TooltipAndDocLink.sveltenew file+14
@@ -0,0 +1,14 @@
1+<script lang="ts">
2+ import Tooltip from "./Tooltip.svelte";
3+ import DocLink from '@/docs/DocLink.svelte'; // TODO try to add a link in the tooltip somehow or something
4+ export let text: string = '';
5+ export let doc: string = '';
6+ let className: string = '';
7+ export { className as class };
8+</script>
9+
10+<Tooltip text={text} enabled={text !== ''} let:tooltipActive={tooltipActive} class={className}>
11+ <DocLink modal path={doc} enabled={doc !== '' && tooltipActive}>
12+ <slot></slot>
13+ </DocLink>
14+</Tooltip>
ui/src/components/docs/Doc.sveltenew file+50
@@ -0,0 +1,50 @@
1+<script lang="ts">
2+ import { createEventDispatcher, onDestroy } from 'svelte';
3+ import DocContent from './DocContent.svelte';
4+ import DocHome from './DocHome.svelte';
5+ import Hamburger from '@/buttons/Hamburger.svelte';
6+ import CloseButton from '@/buttons/CloseButton.svelte';
7+ import keys from 'stores/keys';
8+
9+ export let path: string;
10+
11+ $: homePage = path === '';
12+
13+ const dispatch = createEventDispatcher();
14+ function close() {
15+ dispatch('close');
16+ }
17+
18+ function navigate(path) {
19+ dispatch('navigate', path);
20+ }
21+
22+ $: {
23+ $keys.globalkeyup.get('escape').set('doc', close);
24+ }
25+
26+ onDestroy(() => {
27+ $keys.globalkeyup.get('escape').delete('doc');
28+ });
29+</script>
30+
31+<div class="rounded-lg bg-white">
32+ <div class="flex p-4 border-navy">
33+ {#if !homePage}
34+ <Hamburger on:click={() => navigate('')} />
35+ {:else}
36+ <div class="w-7 h-7" />
37+ {/if}
38+ <div class="grow text-center text-xl">
39+ Help
40+ </div>
41+ <CloseButton on:click={close} />
42+ </div>
43+ <div class="p-8 pt-0">
44+ {#if !homePage}
45+ <DocContent {path} on:navigate />
46+ {:else}
47+ <DocHome on:navigate />
48+ {/if}
49+ </div>
50+</div>
ui/src/components/docs/DocContent.sveltenew file+37
@@ -0,0 +1,37 @@
1+<script lang="ts">
2+
3+ import { createEventDispatcher } from 'svelte';
4+
5+ import docLinks from "actions/docLinks";
6+ import docs from "stores/docs";
7+
8+ import LoadingSpinner from "@/common/LoadingSpinner.svelte";
9+
10+ export let path:string;
11+
12+ const dispatch = createEventDispatcher();
13+ function navigate(path) {
14+ dispatch('navigate', path);
15+ }
16+
17+ function convertLinks(html: string): string {
18+ let converted = html;
19+ const externalLinkRegex = /href="http/g;
20+ converted = converted.replace(externalLinkRegex, 'target="_blank" href="http');
21+ return converted;
22+ }
23+</script>
24+
25+<div class="doc">
26+ {#await docs.getDoc(path)}
27+ <LoadingSpinner spinnerClass="text-black" />
28+ {:then docHtml}
29+ <div use:docLinks={navigate}>
30+ {@html convertLinks(docHtml)}
31+ </div>
32+ {:catch error}
33+ <h1>Oops!</h1>
34+ <h2>Couldn't load the doc at /{path}</h2>
35+ <p>Please DM ~midlev-mindyr so he can fix this.</p>
36+ {/await}
37+</div>
ui/src/components/docs/DocHome.sveltenew file+76
@@ -0,0 +1,76 @@
1+<script lang="ts">
2+ import DocLink from "./DocLink.svelte";
3+
4+ function convertLinks(html: string): string {
5+ let converted = html;
6+ const externalLinkRegex = /href="http/g;
7+ converted = converted.replace(externalLinkRegex, 'target="_blank" href="http');
8+ return converted;
9+ }
10+</script>
11+
12+<div class="doc w-auto mx-auto">
13+ <h1 class="text-center">Table of Contents</h1>
14+ <DocLink path="urbit-id" on:navigate>
15+ <h2>What is an Urbit ID?</h2>
16+ </DocLink>
17+ <!-- <h2>Ship Classes</h2> -->
18+ <ul>
19+ <li>
20+ <DocLink path="galaxy" on:navigate>
21+ <h3>Galaxies</h3>
22+ </DocLink>
23+ </li>
24+ <li>
25+ <DocLink path="star" on:navigate>
26+ <h3>Stars</h3>
27+ </DocLink>
28+ </li>
29+ <li>
30+ <DocLink path="planet" on:navigate>
31+ <h3>Planets</h3>
32+ </DocLink>
33+ </li>
34+ <li>
35+ <DocLink path="moon" on:navigate>
36+ <h3>Moons</h3>
37+ </DocLink>
38+ </li>
39+ <li>
40+ <DocLink path="comet" on:navigate>
41+ <h3>Comets</h3>
42+ </DocLink>
43+ </li>
44+ </ul>
45+ <DocLink path="patpee" on:navigate>
46+ <h2>What is a @p?</h2>
47+ </DocLink>
48+ <ul>
49+ <li>
50+ <DocLink path="phonemes" on:navigate>
51+ <h3>Phonemes - Prefixes & Suffixes</h3>
52+ </DocLink>
53+ </li>
54+ </ul>
55+ <DocLink path="sigil" on:navigate>
56+ <h2>What is a Sigil?</h2>
57+ </DocLink>
58+ <DocLink path="azimuth" on:navigate>
59+ <h2>What is Azimuth?</h2>
60+ </DocLink>
61+ <ul>
62+ <li>
63+ <DocLink path="l2" on:navigate>
64+ <h3>Layer 1 and Layer 2</h3>
65+ </DocLink>
66+ </li>
67+ <li>
68+ <DocLink path="keys" on:navigate>
69+ <h3>Networking Keys</h3>
70+ </DocLink>
71+ </li>
72+ </ul>
73+ <DocLink path="astrolabe" on:navigate>
74+ <h2>About Astrolabe</h2>
75+ </DocLink>
76+</div>
ui/src/components/docs/DocLink.sveltenew file+26
@@ -0,0 +1,26 @@
1+<script lang="ts">
2+ import { createEventDispatcher } from 'svelte';
3+ import docs from 'stores/docs';
4+
5+ export let path:string;
6+ export let modal:boolean = false;
7+ export let asLink:boolean = true;
8+ export let enabled:boolean = true;
9+
10+ const dispatch = createEventDispatcher();
11+ function navigate() {
12+ if (modal) {
13+ docs.show(path);
14+ } else {
15+ dispatch('navigate', path);
16+ }
17+ }
18+</script>
19+
20+{#if enabled}
21+ <a class:no-underline={!asLink} href="javascript:void(0)" on:click={navigate}>
22+ <slot />
23+ </a>
24+{:else}
25+ <slot />
26+{/if}
ui/src/components/docs/HelpModal.sveltenew file+25
@@ -0,0 +1,25 @@
1+<script lang="ts">
2+ import docs from 'stores/docs';
3+ import Doc from './Doc.svelte';
4+
5+ function close() {
6+ docs.hide()
7+ }
8+
9+ function navigate({ detail: path }) {
10+ docs.show(path);
11+ }
12+</script>
13+
14+{#if $docs.show}
15+ <div class="absolute w-full h-full bg-navy opacity-50 cursor-pointer z-50" on:click/>
16+ <div class="absolute w-full h-full z-50 overflow-y-auto" on:click={close}>
17+ <div class="mx-4 2xs:mx-8 md:max-w-xl md:mx-auto">
18+ <div class="py-4 2xs:py-8">
19+ <div on:click|stopPropagation>
20+ <Doc path={$docs.path} on:close={close} on:navigate={navigate} />
21+ </div>
22+ </div>
23+ </div>
24+ </div>
25+{/if}
ui/src/components/extensions/AppIcon.sveltenew file+61
@@ -0,0 +1,61 @@
1+<script lang="ts">
2+ import CopyToClipboard from 'svelte-copy-to-clipboard';
3+ import { uxToHex } from 'lib/utils';
4+ import { getAppByPath } from 'lib/apps';
5+ import store from 'stores/store';
6+ import LoadingSpinner from '@/common/LoadingSpinner.svelte';
7+
8+ export let path: string;
9+
10+ $: desk = path.split('/')[1];
11+ $: appPromise = getAppByPath(path);
12+ $: appUrbitGraphLink = `web+urbitgraph://${path}`;
13+ $: appLink = `/apps/grid/perma?ext=${appUrbitGraphLink}`;
14+
15+ let overrideText = null;
16+
17+ const handleSuccessfullyCopied = (e) => {
18+ overrideText = 'Copied!';
19+ setTimeout(() => {
20+ overrideText = null;
21+ }, 1000);
22+ }
23+
24+ const handleFailedCopy = () => {
25+ alert('failed to copy :(');
26+ }
27+</script>
28+
29+<div class="w-20 text-sm text-center">
30+ <a class="block w-20 h-20 border border-gray-300 bg-gray-600 text-white rounded-lg overflow-hidden"
31+ href={appLink} target="_blank">
32+ {#await appPromise}
33+ <div class="flex h-full items-center">
34+ <LoadingSpinner />
35+ </div>
36+ {:then app}
37+ <div style:background-color={uxToHex(app.color)} class="h-full w-full text-sm">
38+ {#if app.image}
39+ <img src={app.image} alt="app icon"
40+ class="aspect-square object-cover w-full h-full"
41+ />
42+ {/if}
43+ </div>
44+ {:catch}
45+ {path}
46+ {/await}
47+ </a>
48+ <CopyToClipboard text={path} on:copy={handleSuccessfullyCopied} on:fail={handleFailedCopy} let:copy>
49+ <span on:click={copy}>
50+ {#if overrideText}
51+ {overrideText}
52+ {:else}
53+ {#await appPromise}
54+ {desk}
55+ {:then app}
56+ {app.title}
57+ {/await}
58+ {/if}
59+ </span>
60+ </CopyToClipboard>
61+</div>
ui/src/components/extensions/AppsShipViewExtension.sveltenew file+56
@@ -0,0 +1,56 @@
1+<script lang="ts">
2+
3+ import { sein } from 'urbit-ob';
4+ import uniq from 'lodash/uniq';
5+ import tooltip from 'actions/tooltip';
6+ import { normalizeId, filterIdsForChildMoons } from 'lib/id';
7+ import { filterObject } from 'lib/utils';
8+ import { addAllies, delAllies } from 'lib/apps';
9+ import store from 'stores/store';
10+ import ExtensionWindow from '@/ExtensionWindow.svelte';
11+ import AppIcon from './AppIcon.svelte';
12+
13+ export let patp: string;
14+ $: moons = filterIdsForChildMoons($store.peers, patp);
15+ $: possibleAllies = [patp, ...moons];
16+ $: knownApps = uniq(Object.values(filterObject($store.apps.allies, (ally) => {
17+ ally = normalizeId(ally);
18+ return patp === ally || sein(ally) === patp;
19+ })).flat());
20+ $: nonAllies = possibleAllies.filter((ally) => !$store.apps.allies[ally]);
21+ $: emptyAllies = possibleAllies.filter((ally) => {
22+ let apps = $store.apps.allies[ally];
23+ return apps && !apps.length;
24+ });
25+</script>
26+<ExtensionWindow name="Apps" halfWidth>
27+ <svelte:fragment slot="top-bar">
28+ <div class="grow m-2 flex justify-end align-center">
29+ {#if nonAllies.length > 0}
30+ <button class="bg-gray-200 ml-3 px-2 rounded"
31+ on:click={() => addAllies(nonAllies)}
32+ >
33+ Check for More
34+ </button>
35+ {/if}
36+ {#if emptyAllies.length > 0}
37+ <button class="bg-gray-200 ml-3 px-2 rounded"
38+ on:click={() => delAllies(emptyAllies)}
39+ >
40+ Stop Watching
41+ <span use:tooltip={emptyAllies.join(', ')}>
42+ {emptyAllies.length} Ship{emptyAllies.length > 1 ? 's': ''}
43+ </span>
44+ </button>
45+ {/if}
46+ </div>
47+ </svelte:fragment>
48+ {#if knownApps.length > 0}
49+ <div class="flex flex-wrap p-2 gap-2 justify-center">
50+ {#each knownApps as app}
51+ <AppIcon path={app} />
52+ {/each}
53+ </div>
54+ {/if}
55+</ExtensionWindow>
56+
ui/src/components/extensions/GroupsShipViewExtension.sveltenew file+15
@@ -0,0 +1,15 @@
1+<script lang="ts">
2+ import { uxToHex } from 'lib/utils';
3+ import { normalizeId } from 'lib/id';
4+ import store from 'stores/store';
5+ import ExtensionWindow from '@/ExtensionWindow.svelte';
6+
7+ export let patp: string;
8+</script>
9+
10+{#if patp}
11+ <ExtensionWindow name="Shared Groups">
12+ TODO: implement for Groups 2, don't bother with Groups 1
13+ </ExtensionWindow>
14+{/if}
15+
ui/src/components/extensions/ProfileShipViewExtension.sveltenew file+52
@@ -0,0 +1,52 @@
1+<script lang="ts">
2+ import SvelteMarkdown from 'svelte-markdown';
3+ import { uxToHex } from 'lib/utils';
4+ import { normalizeId } from 'lib/id';
5+ import store from 'stores/store';
6+ import Sigil from "@/common/Sigil.svelte";
7+ import ExtensionWindow from '@/ExtensionWindow.svelte';
8+
9+ export let patp: string;
10+ $: contact = $store.contacts[normalizeId(patp)];
11+ $: color = contact && uxToHex(contact.color);
12+ $: somethingToShow = contact && (contact.nickname || contact.cover || contact.avatar || contact.bio);
13+</script>
14+
15+{#if somethingToShow}
16+ <ExtensionWindow name="Groups Profile">
17+ <svelte:fragment slot="top-bar">
18+ {#if contact.nickname}
19+ <div class="grow m-1 flex justify-center align-center">
20+ {contact.nickname}
21+ </div>
22+ {/if}
23+ </svelte:fragment>
24+ <div class="flex flex-wrap py-2">
25+ {#if contact.cover}
26+ <img src={contact.cover} alt="profile cover image"
27+ class="m-1 -mb-16 w-full h-48 border border-black rounded-lg object-cover min-w-0"
28+ />
29+ {/if}
30+ <div class="flex flex-wrap md:flex-nowrap justify-center">
31+ <div class="mx-8 max-w-[128px] min-w-[128px] h-fit grow overflow-hidden rounded-lg">
32+ {#if contact.avatar}
33+ <img src={contact.avatar} alt="custom avatar"
34+ class="aspect-square object-cover max-w-[128px] min-w-0"
35+ />
36+ {:else}
37+ <Sigil patp={patp} size={128} bgColor={color} useNew />
38+ {/if}
39+ </div>
40+ {#if contact.bio}
41+ <div class="text-sm p-3 bg-white rounded-tl-lg rounded-br-lg whitespace-pre-line">
42+ <SvelteMarkdown source={contact.bio} />
43+ </div>
44+ {/if}
45+ </div>
46+ <!-- <p class="whitespace-pre-line">
47+ {contact.bio}
48+ </p> -->
49+ </div>
50+ </ExtensionWindow>
51+{/if}
52+
ui/src/components/pals/PalStatusIndicator.sveltenew file+191
@@ -0,0 +1,191 @@
1+<script lang="ts">
2+ import type { PalStatus } from 'lib/pals';
3+ import tooltip from 'actions/tooltip';
4+ export let status: PalStatus = 'unconnected';
5+ export let acked: boolean = true;
6+ let className: string = '';
7+ export { className as class };
8+
9+ let statusDescription = '', viewBox = '', width = '25';
10+ $: {
11+ switch (status) {
12+ case 'mutual':
13+ statusDescription = 'you are pals'
14+ viewBox = '12 12 100 100';
15+ width = '25';
16+ break;
17+ case 'outgoing':
18+ statusDescription = 'you added them in pals'
19+ viewBox = '0 12 68 100';
20+ width = '17';
21+ if (!acked) {
22+ statusDescription += ' (pending)'
23+ }
24+ break;
25+ case 'incoming':
26+ statusDescription = 'they added you in pals'
27+ viewBox = '24 12 76 100';
28+ width = '19';
29+ break;
30+ }
31+ }
32+</script>
33+{#if status !== 'unconnected'}
34+ <svg width={width} height="25" {viewBox} fill="none" xmlns="http://www.w3.org/2000/svg"
35+ use:tooltip={statusDescription}
36+ class={className}
37+ >
38+
39+ {#if status == 'mutual'}
40+ <path d="M108 50
41+ C108 61.9348 103.259 73.3807 94.8198 81.8198
42+ C86.3807 90.2589 74.9347 95 63 95
43+ C51.0653 95 39.6193 90.2589 31.1802 81.8198
44+ C22.7411 73.3807 18 61.9347 18 50" stroke="black" stroke-width="10"></path><path d="M87.5114 31.5994
45+ C87.5114 28.4354 84.9226 25.8466 81.7585 25.8466
46+ C78.5945 25.8466 76.0057 28.4354 76.0057 31.5994
47+ C76.0057 34.7635 78.5945 37.3523 81.7585 37.3523
48+ C84.9226 37.3523 87.5114 34.7635 87.5114 31.5994
49+ Z
50+ M51.0767 31.5994
51+ C51.0767 28.4354 48.4879 25.8466 45.3239 25.8466
52+ C42.1598 25.8466 39.571 28.4354 39.571 31.5994
53+ C39.571 34.7635 42.1598 37.3523 45.3239 37.3523
54+ C48.4879 37.3523 51.0767 34.7635 51.0767 31.5994
55+ Z" fill="black"></path>
56+ {:else if status == 'outgoing' }
57+ {#if acked}
58+ <path d="M50 95
59+ C44.0905 95 38.2389 93.836 32.7792 91.5746
60+ C27.3196 89.3131 22.3588 85.9984 18.1802 81.8198
61+ C14.0016 77.6412 10.6869 72.6804 8.42542 67.2208
62+ C6.16396 61.7611 5 55.9095 5 50" stroke="black" stroke-width="10"></path><path d="M30.5546 65.9099
63+ L28.7868 67.6777
64+ L32.3223 71.2132
65+ L34.0901 69.4454
66+ L30.5546 65.9099
67+ Z
68+ M67.6777 32.3223
69+ L39.7938 39.7938
70+ L60.2062 60.2062
71+ L67.6777 32.3223
72+ Z
73+ M34.0901 69.4454
74+ L53.5355 50
75+ L50 46.4645
76+ L30.5546 65.9099
77+ L34.0901 69.4454
78+ Z" fill="black"></path>
79+ {:else}
80+ <path d="M50 95
81+ C44.0905 95 38.2389 93.836 32.7792 91.5746
82+ C27.3196 89.3131 22.3588 85.9984 18.1802 81.8198
83+ C14.0016 77.6412 10.6869 72.6804 8.42542 67.2208
84+ C6.16396 61.7611 5 55.9095 5 50" stroke="black" stroke-width="10"></path><path d="M31.4384 66.7938
85+ L30.5546 67.6777
86+ L32.3223 69.4454
87+ L33.2062 68.5616
88+ L31.4384 66.7938
89+ Z
90+ M67.6777 32.3223
91+ L53.7357 36.0581
92+ L63.9419 46.2643
93+ L67.6777 32.3223
94+ Z
95+ M33.2062 68.5616
96+ L34.974 66.7938
97+ L33.2062 65.026
98+ L31.4384 66.7938
99+ L33.2062 68.5616
100+ Z
101+ M38.5095 63.2583
102+ L42.045 59.7227
103+ L40.2773 57.955
104+ L36.7417 61.4905
105+ L38.5095 63.2583
106+ Z
107+ M45.5806 56.1872
108+ L49.1161 52.6517
109+ L47.3483 50.8839
110+ L43.8128 54.4194
111+ L45.5806 56.1872
112+ Z
113+ M52.6516 49.1161
114+ L56.1872 45.5806
115+ L54.4194 43.8128
116+ L50.8839 47.3484
117+ L52.6516 49.1161
118+ Z
119+ M59.7227 42.0451
120+ L63.2583 38.5095
121+ L61.4905 36.7418
122+ L57.9549 40.2773
123+ L59.7227 42.0451
124+ Z
125+ M30.5546 65.9099
126+ L28.7868 67.6777
127+ L32.3223 71.2132
128+ L34.0901 69.4454
129+ L30.5546 65.9099
130+ Z
131+ M67.6777 32.3223
132+ L39.7938 39.7938
133+ L60.2062 60.2062
134+ L67.6777 32.3223
135+ Z
136+ M34.0901 69.4454
137+ L35.8579 67.6777
138+ L32.3223 64.1421
139+ L30.5546 65.9099
140+ L34.0901 69.4454
141+ Z
142+ M39.3934 64.1421
143+ L42.9289 60.6066
144+ L39.3934 57.0711
145+ L35.8579 60.6066
146+ L39.3934 64.1421
147+ Z
148+ M46.4645 57.0711
149+ L50 53.5355
150+ L46.4645 50
151+ L42.9289 53.5355
152+ L46.4645 57.0711
153+ Z
154+ M53.5355 50
155+ L57.0711 46.4645
156+ L53.5355 42.9289
157+ L50 46.4645
158+ L53.5355 50
159+ Z
160+ M60.6066 42.9289
161+ L64.1421 39.3934
162+ L60.6066 35.8579
163+ L57.0711 39.3934
164+ L60.6066 42.9289
165+ Z" fill="black"></path>
166+ {/if}
167+ {:else if status == 'incoming' }
168+ <path d="M95 50
169+ C95 55.9095 93.836 61.7611 91.5746 67.2208
170+ C89.3131 72.6804 85.9984 77.6412 81.8198 81.8198
171+ C77.6412 85.9984 72.6804 89.3131 67.2208 91.5746
172+ C61.7611 93.836 55.9095 95 50 95" stroke="black" stroke-width="10"></path><path d="M67.2383 68.7383
173+ L59.7669 40.8545
174+ L39.3545 61.2669
175+ L67.2383 68.7383
176+ Z
177+ M31.5294 29.4939
178+ L29.7617 27.7262
179+ L26.2261 31.2617
180+ L27.9939 33.0295
181+ L31.5294 29.4939
182+ Z
183+ M53.0962 51.0607
184+ L31.5294 29.4939
185+ L27.9939 33.0295
186+ L49.5607 54.5962
187+ L53.0962 51.0607
188+ Z" fill="black"></path>
189+ {/if}
190+ </svg>
191+{/if}
ui/src/components/pals/PalTagger.sveltenew file+40
@@ -0,0 +1,40 @@
1+<script lang="ts">
2+ import { getPal, tagPal, untagPal } from 'lib/pals';
3+ import store from 'stores/store';
4+
5+ export let patp: string;
6+
7+ $: pal = getPal($store.pals, patp);
8+
9+ let newTagText = '';
10+ $: newTags = newTagText.split(',').map(t => t.trim());
11+ $: sanitizedNewTags = newTags.map(t => t.toLocaleLowerCase().replaceAll(/[^-_.~a-z0-9]+/g, '_'));
12+ $: newTagsAreValid = newTags.every(tagIsValid);
13+ $: validationClasses = newTagsAreValid ? '' : 'border-red-500 bg-red-100'
14+
15+ function tagIsValid(tag: string): boolean {
16+ return /^[-_.~a-z0-9]*$/.test(tag);
17+ }
18+
19+ async function onTagSubmit({ key }) {
20+ if (newTagText && key == 'Enter') {
21+ await tagPal(patp, sanitizedNewTags);
22+ newTagText = '';
23+ }
24+ }
25+</script>
26+
27+<div class="flex flex-wrap gap-1 text-sm justify-center">
28+ {#each pal.tags as tag}
29+ <div class="flex bg-gray-200 rounded divide-gray-500 divide-x items-center">
30+ <span class="px-1">
31+ {tag}
32+ </span>
33+ <button class="px-1 text-gray-500" on:click={() => untagPal(patp, tag)}>
34+ X
35+ </button>
36+ </div>
37+ {/each}
38+</div>
39+<input type="text" class="px-1 text-sm border border-gray-400 rounded {validationClasses}"
40+ on:keydown={onTagSubmit} bind:value={newTagText} placeholder="add_tags, like_this" />
ui/src/components/pals/PalsShipViewExtension.sveltenew file+34
@@ -0,0 +1,34 @@
1+<script lang="ts">
2+ import { getPal, addPal, removePal } from 'lib/pals';
3+ import store from 'stores/store';
4+ import ExtensionWindow from '@/ExtensionWindow.svelte';
5+ import PalStatusIndicator from './PalStatusIndicator.svelte';
6+ import PalTagger from './PalTagger.svelte';
7+
8+ export let patp: string;
9+
10+ $: pal = getPal($store.pals, patp);
11+ $: palAdded = pal.status == 'outgoing' || pal.status == 'mutual';
12+ $: [buttonText, buttonFunc] = palAdded ? ['Remove Pal', removePal] : ['Add Pal', addPal];
13+ $: itsUs = patp.substring(1) === window.ship;
14+</script>
15+
16+{#if $store.palsInstalled && !itsUs}
17+ <ExtensionWindow name="%pals" halfWidth>
18+ <svelte:fragment slot="top-bar">
19+ <div class="grow ml-1 my-2 flex justify-center align-center">
20+ <PalStatusIndicator status={pal.status} acked={pal.ack} />
21+ <button class="bg-gray-200 ml-3 px-2 rounded" on:click={() => buttonFunc(patp)}>
22+ {buttonText}
23+ </button>
24+ </div>
25+ </svelte:fragment>
26+
27+ {#if palAdded}
28+ <div class="flex flex-wrap justify-center gap-3 my-3 conteents">
29+ <PalTagger {patp}></PalTagger>
30+ </div>
31+ {/if}
32+ </ExtensionWindow>
33+{/if}
34+
ui/src/components/search/SearchBar.sveltenew file+152
@@ -0,0 +1,152 @@
1+<script lang="ts">
2+ import SigilInput from './sigil/SigilInput.svelte';
3+ import Symbol from './sigil/Symbol.svelte';
4+
5+ import docs from 'stores/docs';
6+ import keys from 'stores/keys';
7+ import { SearchAnalysis } from 'lib/id';
8+ import { SigilQuery } from 'lib/sigil';
9+
10+ export let patp: string = undefined;
11+ export let analysis: SearchAnalysis = new SearchAnalysis();
12+ export let search = '';
13+ export let sigilQuery: SigilQuery = new SigilQuery('planet');
14+ sigilQuery.urlString = search;
15+ export let searchMode: ('patp' | 'sigil') = 'patp';
16+ export let allowSigilSearch: boolean = true;
17+ let defaultPlaceholderText = "Search by @p or #. '*' matches any character";
18+ export let placeholderText = defaultPlaceholderText;
19+
20+ $: {
21+ placeholderText = placeholderText ? placeholderText : defaultPlaceholderText;
22+ }
23+ $: {
24+ searchMode = allowSigilSearch ? searchMode : 'patp';
25+ }
26+ $: showSigilInput = searchMode == 'sigil';
27+
28+ let bouncySearch: string = search;
29+ let debouncedSearch: string = bouncySearch;
30+
31+ let timer;
32+ $: {
33+ if (!showSigilInput){
34+ if (bouncySearch !== search) {
35+ clearTimeout(timer);
36+ timer = setTimeout(() => {
37+ search = bouncySearch;
38+ }, 300);
39+ }
40+ }
41+ }
42+
43+ function updateSigilUrlString() {
44+ if (showSigilInput) {
45+ if (search !== sigilQuery.urlString) {
46+ sigilQuery.urlString = search;
47+ }
48+ }
49+ }
50+
51+ function updateSigilSearch() {
52+ if (showSigilInput) {
53+ if (sigilQuery.isNotEmpty) {
54+ search = sigilQuery.urlString;
55+ } else {
56+ search = '';
57+ }
58+ }
59+ }
60+
61+ $: search, updateSigilUrlString();
62+ $: sigilQuery.urlString, updateSigilSearch();
63+
64+ $: {
65+ if (showSigilInput) {
66+ if (sigilQuery.isDefinitive) {
67+ patp = sigilQuery.patp;
68+ } else {
69+ patp = undefined;
70+ }
71+ } else {
72+ analysis = new SearchAnalysis(search);
73+ if (analysis.patpIsValid) {
74+ patp = analysis.patp;
75+ } else {
76+ patp = undefined;
77+ }
78+ bouncySearch = search = analysis.search;
79+ }
80+ }
81+
82+ let searchInput;
83+ let searchFocused = false;
84+ function onFocus() { searchFocused = true; }
85+ function onBlur() { searchFocused = false; }
86+ function focus() { if (searchInput) searchInput.focus() }
87+ function blur() { if (searchInput) searchInput.blur() }
88+ $:{
89+ $keys.keyup.get('/').set('searchBar', focus);
90+ // generic binding in App.svelte takes care of blur
91+ $keys.keyup.get('p').set('searchBar', closeSigilInput);
92+ $keys.keyup.get('s').set('searchBar', openSigilInput);
93+ }
94+
95+ function openSigilInput() {
96+ if (allowSigilSearch)
97+ searchMode = 'sigil';
98+ }
99+
100+ function closeSigilInput() {
101+ searchMode = 'patp';
102+ bouncySearch = patp || analysis.search;
103+ debouncedSearch = bouncySearch;
104+ search = debouncedSearch;
105+ }
106+
107+ function showSigilDoc() {
108+ docs.show('sigil-input');
109+ }
110+
111+ const buttonClasses = 'rounded-full bg-black text-white text-sm transition-opacity opacity-50 hover:opacity-80';
112+</script>
113+
114+<div class="relative max-w-md w-full">
115+ {#if showSigilInput}
116+ <div class="rounded-2xl bg-white overflow-hidden">
117+ <SigilInput bind:sigilQuery></SigilInput>
118+ </div>
119+ <button
120+ on:click={showSigilDoc}
121+ class="absolute top-2 left-2 w-6 h-6 {buttonClasses}"
122+ >
123+ ?
124+ </button>
125+ <button
126+ on:click={closeSigilInput}
127+ class="absolute top-2 right-2 w-20 h-6 {buttonClasses}"
128+ >
129+ patp or #
130+ </button>
131+ {:else}
132+ <input type="text" class="p-4 py-2 w-full rounded-full"
133+ spellcheck="false"
134+ placeholder={placeholderText}
135+ on:input={(e) => bouncySearch = e.target.value}
136+ on:focus={onFocus} on:blur={onBlur}
137+ bind:this={searchInput}
138+ value={search}
139+ autofocus
140+ />
141+ {#if allowSigilSearch}
142+ <button
143+ on:click={openSigilInput}
144+ class="absolute top-1 right-1 w-8 h-8 {buttonClasses}"
145+ >
146+ <Symbol components={'gci.lvf.lhf.lbhb.atrf4.al3.cbl2lf.cbl2mb'.split('.')} size={32}
147+ altBgColor="transparent"
148+ />
149+ </button>
150+ {/if}
151+ {/if}
152+</div>
ui/src/components/SearchResultNavButtons.svelte → ui/src/components/search/SearchResultNavButtons.svelterenamed

The content is the same.

ui/src/components/search/SearchResults.sveltenew file+147
@@ -0,0 +1,147 @@
1+<script lang="ts">
2+
3+ import type { Patp, Rolodex } from '@urbit/api';
4+ import { searchPoints } from 'lib/api';
5+ import type { SigilQuery } from 'lib/sigil';
6+ import { searchedContacts } from 'stores/searchStores';
7+ import ShipListings from '@/ShipListings.svelte';
8+ import SearchSettings from './SearchSettings.svelte';
9+ import SearchResultsNavButtons from './SearchResultsNavButtons.svelte';
10+
11+ export let regexQuery: RegExp;
12+ export let sigilQuery: SigilQuery;
13+ export let patpSearch: string;
14+ export let searchMode: ('patp' | 'sigil') = 'patp';
15+
16+ let combinedSearchResults = [];
17+ let searchedPointsP: Promise<any>;
18+ let searchedPoints: Patp[] = [];
19+ let selectedShipIndex: number;
20+ let page: number = 0;
21+ let pageSize: number = 50;
22+ let totalPages, firstItemOnPage;
23+ type status = ('init' | 'prog' | 'done' | 'fail');
24+ let searchStatus: status = 'init';
25+ let notification: string = null;
26+
27+ let timer;
28+ $: {
29+ clearTimeout(timer);
30+ timer = setTimeout(() => {
31+ if (searchMode == 'patp') {
32+ searchedContacts.searchPatp(regexQuery);
33+ } else if (searchMode == 'sigil') {
34+ searchedContacts.searchSigil(sigilQuery.querySyls);
35+ }
36+ }, 1000);
37+ }
38+
39+ function doSearch() {
40+ const searchSnap = search;
41+ searchStatus = 'prog';
42+ console.log(`starting search for "${searchSnap}"`);
43+ searchedPointsP = searchPoints(searchSnap, searchMode);
44+ searchedPointsP.then((points) => {
45+ if (search === searchSnap) {
46+ searchedPoints = points;
47+ searchStatus = 'done';
48+ console.log(`done searching for "${searchSnap}"`);
49+ } else {
50+ console.log(`throwing out results for outdated search "${searchSnap}" (currently on ${search})`);
51+ }
52+ }).catch((err) => {
53+ if (search === searchSnap) {
54+ searchedPoints = [];
55+ searchStatus = 'fail';
56+ }
57+ });
58+ }
59+ $: search = (searchMode === 'sigil') ? sigilQuery.string : patpSearch;
60+ $: [search], doSearch();
61+
62+ $: {
63+ const contactSearchResults: Rolodex = JSON.parse(JSON.stringify($searchedContacts));
64+ const contacts = [];
65+ const nonContacts = [];
66+ searchedPoints.forEach(patp => {
67+ const contact = contactSearchResults[patp];
68+ if (contact) {
69+ contacts.push({ ...contact, patp });
70+ delete contactSearchResults[patp];
71+ } else {
72+ nonContacts.push({ patp });
73+ }
74+ });
75+ const nonAzimuthContacts = Object.entries(contactSearchResults).map(([patp, ship]) => {
76+ return {
77+ ...ship,
78+ patp,
79+ };
80+ });
81+ combinedSearchResults = [...contacts, ...nonAzimuthContacts, ...nonContacts];
82+ if (combinedSearchResults.length === 1) {
83+ selectedShipIndex = 0;
84+ } else {
85+ selectedShipIndex = null;
86+ }
87+ }
88+ $: {
89+ totalPages = Math.ceil(combinedSearchResults.length / pageSize);
90+ firstItemOnPage = page * pageSize;
91+ if (combinedSearchResults.length > 0) {
92+ if (firstItemOnPage >= combinedSearchResults.length) {
93+ page = totalPages - 1;
94+ } else if (firstItemOnPage < 0) {
95+ page = 0;
96+ }
97+ }
98+ }
99+ $: pageResults = combinedSearchResults.slice(firstItemOnPage, (page + 1) * pageSize);
100+ $: itemRangeText = pageResults.length == combinedSearchResults.length ? 'all' :
101+ `${firstItemOnPage + 1}-${firstItemOnPage + pageResults.length}`;
102+
103+ $: {
104+ if (searchStatus == 'prog') {
105+ notification = 'Searching all spawned points...';
106+ } else if (searchStatus == 'fail') {
107+ notification = 'Your search is too broad, please be more specific.';
108+ } else if (searchStatus == 'done' && combinedSearchResults.length === 0) {
109+ notification = 'No spawned ships match your search.'
110+ } else {
111+ notification = null;
112+ }
113+ }
114+</script>
115+
116+<SearchSettings/>
117+{#if notification}
118+<div class="rounded-lg bg-white overflow-hidden">
119+ <p class="py-4 px-6 text-center">
120+ {notification}
121+ </p>
122+</div>
123+{/if}
124+{#if combinedSearchResults.length > 0}
125+ <div class="max-w-md w-full rounded-lg bg-white overflow-hidden">
126+ <SearchResultsNavButtons {page} {pageSize} {totalPages}
127+ on:updatePage={({ detail }) => page = detail.page}
128+ >
129+ <p class="px-4 py-8 text-center">
130+ Showing {itemRangeText} of {combinedSearchResults.length} results
131+ </p>
132+ </SearchResultsNavButtons>
133+ <ShipListings
134+ ships={pageResults}
135+ linkToShips differentiateContacts
136+ />
137+ {#if pageResults.length >= 5}
138+ <SearchResultsNavButtons {page} {pageSize} {totalPages}
139+ on:updatePage={({ detail }) => page = detail.page}
140+ >
141+ <p class="px-4 py-8 text-center">
142+ Showing {itemRangeText} of {combinedSearchResults.length} results
143+ </p>
144+ </SearchResultsNavButtons>
145+ {/if}
146+ </div>
147+{/if}
ui/src/components/search/SearchResultsNavButtons.sveltenew file+54
@@ -0,0 +1,54 @@
1+<script lang="ts">
2+ import { createEventDispatcher } from 'svelte';
3+ export let page: number;
4+ export let pageSize: number;
5+ export let totalPages: number;
6+ const dispatch = createEventDispatcher();
7+
8+ function updatePage(page: number) {
9+ dispatch('updatePage', { page });
10+ }
11+
12+ function visitPrevious() {
13+ updatePage(page - 1);
14+ }
15+
16+ function visitNext() {
17+ updatePage(page + 1);
18+ }
19+
20+ function seeList() {
21+ updatePage(null);
22+ }
23+</script>
24+
25+{#if totalPages > 1}
26+ <div class="flex items-center px-8 max-w-md w-full">
27+ <div class="justify-self-start h-6">
28+ <button
29+ on:click={visitPrevious}
30+ class="h-6 w-12 bg-gold"
31+ class:invisible={!(page > 0)}
32+ style="
33+ clip-path: polygon(25% 0%, 0% 50%, 25% 100%, 100% 100%, 75% 50%, 100% 0%);
34+ "
35+ >
36+ </button>
37+ </div>
38+ <div class="grow">
39+ <slot/>
40+ </div>
41+ <div class="justify-self-end h-6">
42+ <button
43+ on:click={visitNext}
44+ class="h-6 w-12 bg-gold"
45+ class:invisible={!(page < totalPages - 1)}
46+ style="
47+
48+ clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 25% 50%, 0% 0%);
49+ "
50+ >
51+ </button>
52+ </div>
53+ </div>
54+{/if}
ui/src/components/search/SearchSettings.sveltenew file+25
@@ -0,0 +1,25 @@
1+<script lang="ts">
2+ import ToggleButton from '../buttons/ToggleButton.svelte';
3+
4+ import { searchSettings } from 'stores/searchStores';
5+ import { toggleStoreKey } from 'lib/utils';
6+
7+ function toggleMoons() {
8+ toggleStoreKey(searchSettings, 'includeMoons');
9+ }
10+
11+ function toggleComets() {
12+ toggleStoreKey(searchSettings, 'includeComets');
13+ }
14+</script>
15+
16+<div class="max-w-md rounded-lg bg-gold overflow-hidden flex flex-wrap items-center justify-center">
17+ <div class="px-4 py-2 flex gap-x-2 items-center border-navy">
18+ <span>Include Moons</span>
19+ <ToggleButton on:click={toggleMoons} on={$searchSettings.includeMoons}></ToggleButton>
20+ </div>
21+ <div class="px-4 py-2 flex gap-x-2 items-center border-navy">
22+ <span>Include Comets</span>
23+ <ToggleButton on:click={toggleComets} on={$searchSettings.includeComets}></ToggleButton>
24+ </div>
25+</div>
ui/src/components/search/sigil/ClanSelect.sveltenew file+44
@@ -0,0 +1,44 @@
1+<script lang="ts">
2+ import ClanSelectOption from './ClanSelectOption.svelte';
3+
4+ import { capitalize } from 'lib/utils';
5+ import { CLANS, Clan } from 'types/sigil';
6+ import keys from 'stores/keys';
7+
8+ export let clan: Clan = 'planet';
9+
10+ let dropdownOpen = false;
11+
12+ function openDropdown() { dropdownOpen = true }
13+ function closeDropdown() { dropdownOpen = false }
14+
15+ function selectClan(itemClan: typeof clan) {
16+ clan = itemClan;
17+ dropdownOpen = false;
18+ }
19+
20+ $: {
21+ $keys.keyup.get('escape').set('clanSelect', closeDropdown);
22+ }
23+</script>
24+
25+<div class="text-xl text-center bg-white">
26+ <p
27+ on:click={openDropdown}
28+ class=" py-2"
29+ >
30+ {capitalize(clan)}
31+ <span class="font-mono">▼</span>
32+ </p>
33+ {#if dropdownOpen}
34+ <div class="absolute z-20 top-1 w-full flex flex-col mx-auto divide-y bg-white rounded-2xl border-b">
35+ <h3 class="py-2" on:click={closeDropdown}>
36+ Select Sigil Type
37+ </h3>
38+ {#each CLANS as itemClan}
39+ <ClanSelectOption clan={itemClan} on:click={() => selectClan(itemClan)} />
40+ {/each}
41+ </div>
42+ {/if}
43+</div>
44+
ui/src/components/search/sigil/ClanSelectOption.sveltenew file+17
@@ -0,0 +1,17 @@
1+<script lang="ts">
2+ import { capitalize } from 'lib/utils';
3+ import MiniFakeSigil from './MiniFakeSigil.svelte';
4+
5+ export let sigilSearch = {};
6+ export let clan: ('galaxy' | 'star' | 'planet') = 'planet';
7+
8+ let dropdownOpen = true;
9+</script>
10+
11+<div class="flex items-center justify-center gap-2 py-2" on:click>
12+ <h3>
13+ {capitalize(clan)}:
14+ </h3>
15+ <MiniFakeSigil {clan} />
16+</div>
17+
ui/src/components/search/sigil/GeonSelector.sveltenew file+30
@@ -0,0 +1,30 @@
1+<script lang="ts">
2+ import SymbolInputModeSelectorButton from './SymbolInputModeSelectorButton.svelte';
3+
4+ import { searchSettings } from 'stores/searchStores';
5+ import type { SymbolQuery } from 'lib/sigil';
6+ import { GEONS } from 'types/sigil';
7+ import { arePartsPlausible } from 'lib/sigil';
8+
9+ export let symbolQuery: SymbolQuery;
10+ export let popMode: Function;
11+
12+ function setGeon(geon) {
13+ symbolQuery.geon = geon;
14+ popMode();
15+ }
16+
17+ $: componentsSansGeon = symbolQuery.components.filter(c => c[0] !== 'g');
18+</script>
19+
20+{#each GEONS as geon}
21+ {@const plausible = $searchSettings.allowFictionalSigils ||
22+ arePartsPlausible(componentsSansGeon, symbolQuery.symbolType, [geon])
23+ }
24+ <SymbolInputModeSelectorButton components={[geon]}
25+ focused={geon === symbolQuery.geon}
26+ enabled={plausible}
27+ on:click={() => setGeon(geon)}
28+ />
29+{/each}
30+
ui/src/components/search/sigil/MiniFakeSigil.sveltenew file+25
@@ -0,0 +1,25 @@
1+<script lang="ts">
2+ import { sigilFromSymbols, stringRenderer as sr, symbolFromDef } from '@johnhyde/sigil-js';
3+
4+ export let clan: ('galaxy' | 'star' | 'planet') = 'planet';
5+
6+ let size = 32;
7+ let squareDef = ['gci'];
8+ let square = symbolFromDef(squareDef);
9+ let sigilProps = {
10+ size,
11+ renderer: sr,
12+ colors: ['white', 'black'],
13+ icon: true,
14+ }
15+ let sigils = {
16+ galaxy: sigilFromSymbols([square], sigilProps),
17+ star: sigilFromSymbols([square, square], sigilProps),
18+ planet: sigilFromSymbols([square, square, square, square], sigilProps),
19+ }
20+ $: sigilWidth = (clan === 'galaxy' ? size / 2 : size);
21+</script>
22+
23+<div style:width="{sigilWidth}px">
24+ {@html sigils[clan]}
25+</div>
ui/src/components/search/sigil/SigilInput.sveltenew file+104
@@ -0,0 +1,104 @@
1+<script lang="ts">
2+ import SymbolInputModeSelector from './SymbolInputModeSelector.svelte';
3+ import SymbolInputNavButtons from './SymbolInputNavButtons.svelte';
4+ import SymbolInput from './SymbolInput.svelte';
5+ import ClanSelect from './ClanSelect.svelte';
6+ import ToggleButton from '@/buttons/ToggleButton.svelte';
7+
8+ import type { SigilQuery } from 'lib/sigil';
9+ import { toggleStoreKey } from 'lib/utils';
10+ import { searchSettings } from 'stores/searchStores';
11+ import keys from 'stores/keys';
12+
13+ export let sigilQuery: SigilQuery;
14+ let focusedSymbolIndex: number = undefined;
15+ let inputComponents: string[] = [];
16+
17+ $: gridClasses = (sigilQuery.clan === 'galaxy' ? 'max-w-[10rem] grid items-center' : 'max-w-[18rem] grid grid-cols-2 items-center');
18+
19+ function unfocusSymbol() {
20+ focusedSymbolIndex = undefined;
21+ }
22+ $: focusedSymbol = sigilQuery.activeSymbols[focusedSymbolIndex];
23+ $: {
24+ const numActiveSymbols = sigilQuery.activeSymbols.length;
25+ if (focusedSymbolIndex >= numActiveSymbols) {
26+ focusedSymbolIndex = numActiveSymbols - 1;
27+ }
28+ }
29+
30+ function toggleAllowFictional() {
31+ toggleStoreKey(searchSettings, 'allowFictionalSigils');
32+ }
33+
34+ function clear() {
35+ sigilQuery = sigilQuery.clearSymbols();
36+ }
37+
38+ $: {
39+ sigilQuery.allowFictional = $searchSettings.allowFictionalSigils;
40+ }
41+
42+ function keyboardClear() {
43+ if (!focusedSymbol) {
44+ clear();
45+ }
46+ }
47+
48+ $: {
49+ $keys.keyup.get('x').set('sigilInput', keyboardClear);
50+ $keys.keyup.get('backspace').set('sigilInput', keyboardClear);
51+ }
52+</script>
53+
54+<div>
55+ <ClanSelect bind:clan={sigilQuery.clan} />
56+ <div class="flex flex-col xs:flex-row">
57+ <div class="grow-[2] w-full xs:m-0 xs:max-w-[18rem]" on:click={unfocusSymbol}>
58+ <div class="min-h-[14rem] mx-auto p-4 {gridClasses} xs:rounded-bl-2xl">
59+ {#each sigilQuery.activeSymbols as symbol, index}
60+ <SymbolInput
61+ bind:symbolQuery={symbol}
62+ {focusedSymbolIndex}
63+ {index}
64+ clan={sigilQuery.clan}
65+ {inputComponents}
66+ on:click={() => focusedSymbolIndex = index}
67+ />
68+ {/each}
69+ </div>
70+ </div>
71+ <div class="px-4 py-2 border-t grow rounded-b-2xl xs:border-l xs:border-t-0 xs:rounded-bl-none">
72+ {#if focusedSymbol}
73+ <SymbolInputModeSelector
74+ bind:symbolQuery={focusedSymbol}
75+ bind:inputComponents
76+ unfocusSymbol={unfocusSymbol}
77+ />
78+ {:else}
79+ <SymbolInputNavButtons onClear={sigilQuery.isNotEmpty ? clear : null} />
80+ <p class="mt-2">
81+ Allow impossible Sigils:
82+ <ToggleButton on:click={toggleAllowFictional} on={$searchSettings.allowFictionalSigils} />
83+ </p>
84+ {/if}
85+ </div>
86+ </div>
87+ <!-- {#each sigilQuery.activeSymbols as symbol}
88+ {@const plausibleSyllables = symbol.plausibleSyllables}
89+ {@const plausibleParts = symbol.plausibleParts}
90+ <p>
91+ {#if plausibleSyllables.length < 20 && plausibleSyllables.length > 0}
92+ {plausibleSyllables.join(', ')}:
93+ {#if plausibleParts.length < 20 && plausibleParts.length > 0}
94+ {plausibleParts.join(', ')}
95+ {:else}
96+ {plausibleParts.length}
97+ {/if}
98+ {:else}
99+ {plausibleSyllables.length}
100+ {/if}
101+ </p>
102+ {/each} -->
103+ <!-- {sigilQuery.string} -->
104+</div>
ui/src/components/search/sigil/Symbol.sveltenew file+79
@@ -0,0 +1,79 @@
1+<script lang="ts">
2+ import { createEventDispatcher } from 'svelte';
3+ import { sigilFromSymbols, stringRenderer as sr, symbolFromDef } from '@johnhyde/sigil-js';
4+ import { sigilScalingFunction } from 'lib/sigil';
5+ import symbolPartClick from 'actions/symbolPartClick';
6+
7+ export let components: string[];
8+ export let size: number;
9+ export let fgColor: string = 'black';
10+ export let bgColor: string = 'white';
11+ export let altBgColor: string = undefined;
12+ export let hoverColor: string = '#8f8';
13+ export let opacity: number = 1;
14+ export let inverted: boolean = false;
15+ export let interactive: boolean = false;
16+ export let strokeWidthFactor: number = 1;
17+ let svgString: any;
18+
19+ const dispatch = createEventDispatcher();
20+
21+ $: {
22+ const symbol = symbolFromDef(components);
23+ let colors = [bgColor, fgColor];
24+ let tempAltBgColor = altBgColor;
25+ if (inverted) {
26+ colors = [fgColor, bgColor];
27+ if (!tempAltBgColor) tempAltBgColor = bgColor;
28+ }
29+ const svgAST = sigilFromSymbols(
30+ [symbol],
31+ {
32+ size,
33+ colors,
34+ margin: false,
35+ autoScaleStrokes: true,
36+ strokeScalingFunctionV2: (s) => {
37+ return strokeWidthFactor * sigilScalingFunction(s);
38+ },
39+ },
40+ );
41+ svgAST.attributes.preserveAspectRatio = 'xMidYMin slice';
42+ svgString = sr(svgAST);
43+ if (tempAltBgColor) {
44+ svgString = svgString.replace(/rect fill="[^"]+"/, `rect fill="${tempAltBgColor}"`);
45+ }
46+ }
47+
48+ function onPartClick(partId: string) {
49+ dispatch('partClick', partId);
50+ }
51+</script>
52+
53+<style lang="scss" global>
54+ .interactive {
55+ svg {
56+ pointer-events: none;
57+ }
58+
59+ path, circle, line {
60+ pointer-events: auto;
61+
62+ &:not([dataisgeon="true"]):hover {
63+ stroke: var(--hoverColor);
64+ }
65+ }
66+
67+ circle:not([dataisgeon="true"]):not([fill="none"]):hover {
68+ fill: var(--hoverColor);
69+ }
70+ }
71+</style>
72+
73+<div class="aspect-square" class:interactive style:max-width="{size}px"
74+ style="--hoverColor: {hoverColor}; opacity: {opacity};"
75+ on:click
76+ use:symbolPartClick={{ onPartClick, enabled: interactive, svgString }}
77+>
78+ {@html svgString}
79+</div>
ui/src/components/search/sigil/SymbolInput.sveltenew file+105
@@ -0,0 +1,105 @@
1+<script lang="ts">
2+ import Symbol from './Symbol.svelte';
3+ import without from 'lodash/without';
4+
5+ import { searchSettings } from 'stores/searchStores';
6+ import type { SymbolQuery } from 'lib/sigil';
7+ import { filterPartsByGeon } from 'lib/sigil';
8+
9+ export let symbolQuery: SymbolQuery;
10+ export let focusedSymbolIndex: number;
11+ export let index: number = 0;
12+ export let clan: string = 'galaxy';
13+ export let inputComponents: string[] = [];
14+ export let fgColor = 'black';
15+ export let bgColor = 'white';
16+ let size = 128;
17+
18+ let translateClass;
19+ $: {
20+ translateClass = 'translate-x-0 translate-y-0';
21+ if (focusedSymbolIndex !== undefined) {
22+ if (clan === 'star') {
23+ translateClass = index ? 'origin-right' : 'origin-left';
24+ } else if (clan === 'planet') {
25+ let cornerIndex = index;
26+ if (!focused) cornerIndex = focusedSymbolIndex;
27+ switch (cornerIndex) {
28+ case 0: translateClass = 'translate-x-1/4 translate-y-1/4'; break;
29+ case 1: translateClass = '-translate-x-1/4 translate-y-1/4'; break;
30+ case 2: translateClass = 'translate-x-1/4 -translate-y-1/4'; break;
31+ case 3:
32+ default: translateClass = '-translate-x-1/4 -translate-y-1/4';
33+ }
34+ }
35+ }
36+ }
37+ $: scaleClass = 'scale-150 ';
38+
39+ $: focused = index === focusedSymbolIndex;
40+ $: focusedClasses = (
41+ focused ? `${scaleClass} z-10`
42+ : (focusedSymbolIndex !== undefined ? 'scale-50' : '' )
43+ );
44+
45+ function onPartDelete({ detail: partId }) {
46+ symbolQuery = symbolQuery.removePart(partId);
47+ }
48+
49+ function onPartClick({ detail: partId }) {
50+ symbolQuery = symbolQuery.addPart(partId);
51+ }
52+
53+ let filteredInputComponents = [];
54+ let inputContainsStrokes;
55+ $: {
56+ if (inputComponents) {
57+ filteredInputComponents = without(inputComponents, ...symbolQuery.components);
58+ } else {
59+ filteredInputComponents = [];
60+ }
61+ filteredInputComponents = filterPartsByGeon(filteredInputComponents, symbolQuery.geon);
62+ }
63+ $: {
64+ inputContainsStrokes = undefined !== filteredInputComponents.find((c) => {
65+ return c[0] === 'l' || c[0] === 'a' || c[0] === 'b';
66+ });
67+ }
68+ $: plausible = $searchSettings.allowFictionalSigils || symbolQuery.isPlausible;
69+</script>
70+
71+<div class="aspect-square relative flex transition {translateClass} {focusedClasses}"
72+ style:max-width="{size}px"
73+ on:click|stopPropagation
74+>
75+ {#if symbolQuery.components.length > 0}
76+ <Symbol components={symbolQuery.components} {size}
77+ inverted={!symbolQuery.geon}
78+ interactive={focused}
79+ strokeWidthFactor={focused ? 2 : 1}
80+ fgColor={!plausible ? 'red' : (symbolQuery.isPerfectMatch ? 'black' : '#333')}
81+ bgColor="white"
82+ altBgColor="transparent"
83+ hoverColor="red"
84+ on:partClick={onPartDelete}
85+ />
86+ {:else}
87+ <div class="border-[1.5px] border-white grow bg-white">
88+ <div class="rounded-md border-4 border-gray-500 h-full"></div>
89+ </div>
90+ {/if}
91+ {#if focused && filteredInputComponents.length}
92+ <div class="absolute inset-0 pointer-events-none">
93+ <Symbol components={filteredInputComponents} {size}
94+ strokeWidthFactor={inputContainsStrokes ? 2.5 : 1}
95+ fgColor={symbolQuery.geon ? bgColor : fgColor}
96+ bgColor={!symbolQuery.geon ? bgColor : fgColor}
97+ altBgColor="transparent"
98+ opacity={0.5}
99+ inverted
100+ interactive
101+ on:partClick={onPartClick}
102+ />
103+ </div>
104+ {/if}
105+</div>
ui/src/components/search/sigil/SymbolInputModeSelector.sveltenew file+168
@@ -0,0 +1,168 @@
1+<script lang="ts">
2+ import SymbolInputNavButtons from './SymbolInputNavButtons.svelte';
3+
4+ import GeonSelector from './GeonSelector.svelte';
5+ import SymbolInputModeSelectorButton from './SymbolInputModeSelectorButton.svelte';
6+
7+ import { searchSettings } from 'stores/searchStores';
8+ import keys from 'stores/keys';
9+ import type { PartType, ModeDef, ModeDefs } from 'types/sigil';
10+ import type { SymbolQuery } from 'lib/sigil';
11+ import { MODE_DEFS } from 'types/sigil';
12+ import { filterPartsByGeon, getDeepParts } from 'lib/sigil';
13+
14+ export let symbolQuery: SymbolQuery = null;
15+ export let inputComponents: string[] = [];
16+ export let unfocusSymbol: Function = () => {};
17+
18+ let mode: string = null;
19+ let subMode: string = null;
20+ let modeDef: ModeDef = undefined;
21+ let unselectedSubModesExist: boolean = false;
22+ let modeDefs: ModeDefs = MODE_DEFS;
23+ let plausibleModeDefs: { name: string, def: ModeDef }[] = [];
24+
25+ function showGeonSelector() {
26+ if (!symbolQuery.components.length && !mode) {
27+ mode = 'geon';
28+ subMode = null;
29+ }
30+ }
31+
32+ $: symbolQuery.components, showGeonSelector();
33+
34+ function pushMode(newMode: string) {
35+ const subModes = modeDef?.modes;
36+ if (subModes || subMode) {
37+ subMode = newMode;
38+ } else {
39+ mode = newMode;
40+ subMode = null;
41+ }
42+ }
43+
44+ function popMode() {
45+ if (mode || subMode) {
46+ mode = null;
47+ subMode = null;
48+ } else {
49+ unfocusSymbol();
50+ }
51+ }
52+
53+ $: {
54+ let modeResolved = false;
55+ let count = 0;
56+ while (!modeResolved && count < 5) {
57+ modeDef = undefined;
58+ modeDefs = MODE_DEFS;
59+ if (mode) {
60+ modeDef = MODE_DEFS[mode];
61+ }
62+ unselectedSubModesExist = !!modeDef?.modes;
63+ if (unselectedSubModesExist) {
64+ modeDefs = modeDef.modes;
65+ if (subMode) {
66+ if (modeDefs[subMode]) {
67+ modeDef = modeDefs[subMode];
68+ } else {
69+ console.error(`Unknown subMode: ${subMode} of ${mode} in defs:`, modeDefs);
70+ subMode = null;
71+ }
72+ }
73+ }
74+ unselectedSubModesExist = !!modeDef?.modes;
75+ if (!isDefPlausible(modeDef) && mode !== 'geon') {
76+ if (subMode) {
77+ subMode = null;
78+ } else {
79+ mode = null;
80+ }
81+ } else {
82+ plausibleModeDefs = getPlausibleModeDefs(modeDefs);
83+ if (unselectedSubModesExist) {
84+ subMode = plausibleModeDefs[0].name;
85+ } else {
86+ modeResolved = true;
87+ }
88+ }
89+ count++;
90+ if (count >= 5 && !modeResolved) {
91+ console.error("sigil input mode resulotion failed");
92+ }
93+ }
94+ inputComponents = [];
95+ if (modeDef?.parts?.length) {
96+ inputComponents = modeDef.parts;
97+ if (!$searchSettings.allowFictionalSigils) {
98+ inputComponents = symbolQuery.filterPlausibleParts(inputComponents);
99+ }
100+ }
101+ }
102+
103+ function isDefPlausible(def: ModeDef): boolean {
104+ if (!def) return true;
105+ const deepParts = getDeepParts(def);
106+ return $searchSettings.allowFictionalSigils || symbolQuery.arePartsPlausible(deepParts);
107+ }
108+
109+ function getPlausibleModeDefs(modeDefs: ModeDefs) {
110+ return Object.entries(modeDefs).map(([modeName, def]) => {
111+ const plausible = isDefPlausible(def);
112+ if (!plausible && modeName !== 'geon') return null;
113+ const parts = filterPartsByGeon(def.displayParts || def.parts, symbolQuery.geon);
114+ return {
115+ name: modeName,
116+ def: {
117+ ...def,
118+ parts,
119+ },
120+ };
121+ }).filter(mode => mode !== null);
122+ }
123+
124+ function clear() {
125+ // If a geon is present it should be preserved, unless it's the only component
126+ // If there's only 1 component, it should be removed
127+ // Otherwise, at least one component might be a geon and should be preserved
128+ if (symbolQuery.components.length === 1) {
129+ symbolQuery = symbolQuery.clear();
130+ } else {
131+ symbolQuery = symbolQuery.clearExceptPartType('geon');
132+ }
133+ }
134+
135+ $: {
136+ $keys.keyup.get('x').set('sigilMode', clear);
137+ $keys.keyup.get('backspace').set('sigilMode', clear);
138+ $keys.keyup.get('escape').set('sigilMode', popMode);
139+ }
140+</script>
141+
142+<style lang="scss">
143+ .grid-cols-custom {
144+ grid-template-columns: repeat(auto-fill, 48px);
145+ }
146+</style>
147+
148+<div class="mx-auto flex justify-center xs:items-center xs:flex-col">
149+ <SymbolInputNavButtons onDone={popMode} onClear={clear} hideClearButton={symbolQuery.components.length == 0} />
150+ <div class="max-w-[15rem] h-full grid grid-cols-custom gap-1 justify-center xs:max-w-[8rem]">
151+ {#if mode === 'geon'}
152+ <GeonSelector bind:symbolQuery {popMode} />
153+ {:else}
154+ {#each plausibleModeDefs as { name, def: { parts } }}
155+ <SymbolInputModeSelectorButton components={parts} focused={mode === name || subMode === name}
156+ on:click={() => pushMode(name)}
157+ />
158+ {/each}
159+ {/if}
160+ </div>
161+ <!-- <p class="break-all w-24">
162+ mode: {mode}
163+ </p>
164+ <p class="break-all w-24">
165+ sub: {subMode}
166+ </p> -->
167+</div>
168+
ui/src/components/search/sigil/SymbolInputModeSelectorButton.sveltenew file+33
@@ -0,0 +1,33 @@
1+<script lang="ts">
2+ import { createEventDispatcher } from 'svelte';
3+ import Symbol from './Symbol.svelte';
4+
5+ export let components: string[] = [];
6+ export let focused: boolean = false;
7+ export let enabled: boolean = true;
8+ export let padding: number = undefined;
9+
10+ const dispatch = createEventDispatcher();
11+ let size = 48;
12+
13+ $: focusedClasses = focused ? 'border-2 border-gold-s1 p-[3px]' : 'border border-gray-500 p-[4px]';
14+ $: enabledClasses = enabled ? '' : 'opacity-50';
15+ $: includesGeon = components.find(c => c[0] === 'g') !== undefined;
16+ $: defaultPadding = includesGeon ? 0 : 0;
17+ $: actualPadding = padding !== undefined ? padding : defaultPadding;
18+
19+ function onClick(e) {
20+ if (enabled) dispatch('click', e);
21+ }
22+</script>
23+<div
24+class="bg-white rounded-md w-[48px] {focusedClasses} {enabledClasses}"
25+on:click={onClick}
26+>
27+<div class:cursor-pointer={enabled}
28+ style:padding="{actualPadding}px"
29+>
30+ <Symbol {components} {size} inverted={!includesGeon} />
31+</div>
32+</div>
33+
ui/src/components/search/sigil/SymbolInputNavButtons.sveltenew file+30
@@ -0,0 +1,30 @@
1+<script lang="ts">
2+ import upArrow from 'assets/up-arrow.svg';
3+ import xIcon from 'assets/x.svg';
4+
5+ export let onDone: () => void = null;
6+ export let onClear: () => void = null;
7+ export let hideDoneButton = false;
8+ export let hideClearButton = false;
9+
10+ $: showDoneButton = (onDone && !hideDoneButton);
11+ $: showClearButton = (onClear && !hideClearButton);
12+
13+ let buttonClasses = 'cursor-pointer border border-gray-500 rounded-md aspect-square w-[48px]';
14+</script>
15+
16+<style lang="scss">
17+ .grid-cols-custom {
18+ grid-template-columns: repeat(auto-fill, 48px);
19+ }
20+</style>
21+
22+<div class="grid gap-1 self-start justify-center mr-1 xs:mr-0 xs:mb-1 xs:self-stretch {(showDoneButton && showClearButton) ? 'grid-cols-custom' : ''}">
23+ {#if showDoneButton}
24+ <img src={upArrow} alt="done" class={buttonClasses} on:click={onDone}/>
25+ {/if}
26+ {#if showClearButton}
27+ <img src={xIcon} alt="clear" class={buttonClasses} on:click={onClear}/>
28+ {/if}
29+ </div>
30+
ui/src/components/ship_view/AzimuthDetails.sveltenew file+90
@@ -0,0 +1,90 @@
1+<script lang="ts">
2+ import { clan } from 'urbit-ob';
3+ import TooltipAndDocLink from '@/common/TooltipAndDocLink.svelte';
4+ import EthAddressLink from '@/common/EthAddressLink.svelte';
5+ import ShipChain from './ShipChain.svelte';
6+
7+ export let patp: string;
8+ export let pointInfo: any = {};
9+
10+
11+ $: shipClass = clan(patp);
12+ $: azPoint = ['galaxy', 'star', 'planet'].includes(shipClass);
13+</script>
14+
15+{#if azPoint && pointInfo.life !== undefined}
16+ {#if shipClass !== 'galaxy'}
17+ <p>
18+ {#if pointInfo.sponsorChain && pointInfo.sponsorChain.length > 0}
19+ <p>
20+ {pointInfo.sponsorChain.length === 1 ? 'Sponsor:' : 'Sponsor Chain:'}
21+ <ShipChain shipChain={pointInfo.sponsorChain}></ShipChain>
22+ </p>
23+ {:else}
24+ Unsponsored
25+ {/if}
26+ </p>
27+ {/if}
28+ <p>
29+ <TooltipAndDocLink
30+ text="Number of times this ship's keys have been set. Must be at least 1 to use the network."
31+ doc="keys"
32+ class="inline"
33+ >
34+ Key Revision:
35+ {pointInfo.life}
36+ </TooltipAndDocLink>
37+ </p>
38+ <p>
39+ <TooltipAndDocLink
40+ text="Number of times this ship has breached."
41+ doc="keys"
42+ class="inline"
43+ >
44+ Factory Resets:
45+ {pointInfo.rift}
46+ </TooltipAndDocLink>
47+ </p>
48+ {#if pointInfo.proxies}
49+ <p>
50+ <span>
51+ Owner:
52+ <EthAddressLink address={pointInfo.proxies.owner.address} />
53+ </span>
54+ </p>
55+ <p>
56+ <span>
57+ Management Proxy:
58+ <EthAddressLink address={pointInfo.proxies['management-proxy'].address}>
59+ <span class="text-gray-700">not set</span>
60+ </EthAddressLink>
61+ </span>
62+ </p>
63+ <p>
64+ <span>
65+ Spawn Proxy:
66+ <EthAddressLink address={pointInfo.proxies['spawn-proxy'].address}>
67+ <span class="text-gray-700">not set</span>
68+ </EthAddressLink>
69+ </span>
70+ </p>
71+ <p>
72+ <span>
73+ Transfer Proxy:
74+ <EthAddressLink address={pointInfo.proxies['transfer-proxy'].address}>
75+ <span class="text-gray-700">not set</span>
76+ </EthAddressLink>
77+ </span>
78+ </p>
79+ {#if shipClass === 'galaxy'}
80+ <p>
81+ <span>
82+ Voting Proxy:
83+ <EthAddressLink address={pointInfo.proxies['voting-proxy'].address}>
84+ [not set]
85+ </EthAddressLink>
86+ </span>
87+ </p>
88+ {/if}
89+ {/if}
90+{/if}
ui/src/components/ship_view/ShipChain.sveltenew file+11
@@ -0,0 +1,11 @@
1+<script lang="ts">
2+ import ShipLink from '@/common/ShipLink.svelte';
3+
4+ export let shipChain: string[];
5+</script>
6+
7+{#each shipChain as ship, index}
8+ {#if index > 0}{' > '}{/if}
9+ <ShipLink patp={ship}></ShipLink>
10+{/each}
11+
ui/src/components/ship_view/ShipChildrenTabs.sveltenew file+136
@@ -0,0 +1,136 @@
1+<script lang="ts">
2+ import { clan } from 'urbit-ob';
3+
4+ import { normalizeId, filterIdsForChildMoons } from 'lib/id';
5+ import { getSpawnedPoints, getUnlockedSpawnedPoints, getLockedSpawnedPoints } from 'lib/api';
6+ import store from 'stores/store';
7+ import ShipListings from '@/ShipListings.svelte';
8+
9+ export let patp: string;
10+ export let spawnedCount: number = undefined;
11+
12+ let rawSpawnedPointsPromise: any;
13+ let rawSpawnedPoints: any = null;
14+ let rawLockedPointsPromise: any;
15+ let rawLockedPoints: any = null;
16+ let spawnedPoints: string[] = [];
17+ let lockedPoints: string[] = [];
18+
19+ $: shipClass = clan(patp);
20+ $: azPoint = ['galaxy', 'star', 'planet'].includes(shipClass);
21+ $: canSpawnPoints = ['galaxy', 'star'].includes(shipClass);
22+ $: spawnableClassPlural = !canSpawnPoints ? '' : (shipClass === 'galaxy' ? 'Star' : 'Planet');
23+ $: {
24+ rawSpawnedPoints = null;
25+ rawLockedPoints = null;
26+ if (canSpawnPoints) {
27+ let galaxy = shipClass === 'galaxy';
28+ let getSpawnedPointsFunc = galaxy ? getUnlockedSpawnedPoints : getSpawnedPoints;
29+ if (galaxy) {
30+ rawLockedPointsPromise = getLockedSpawnedPoints(patp);
31+ rawLockedPointsPromise.then((info) => {
32+ rawLockedPoints = info;
33+ }).catch((error) => {
34+ rawLockedPoints = { error };
35+ });
36+ }
37+ rawSpawnedPointsPromise = getSpawnedPointsFunc(patp);
38+ rawSpawnedPointsPromise.then((info) => {
39+ rawSpawnedPoints = info;
40+ }).catch((error) => {
41+ rawSpawnedPoints = { error };
42+ });
43+ }
44+ }
45+ $: {
46+ spawnedPoints = [];
47+ if (rawSpawnedPoints?.points) {
48+ spawnedPoints = rawSpawnedPoints?.points.map(patpToShip);
49+ }
50+ }
51+ $: {
52+ lockedPoints = [];
53+ if (rawLockedPoints?.points) {
54+ lockedPoints = rawLockedPoints?.points.map(patpToShip);
55+ }
56+ }
57+ $: trueSpawnedCount = spawnedCount || spawnedPoints.length;
58+ $: spawnedTab = {
59+ name: 'Spawned',
60+ plural: 'Spawned ' + spawnableClassPlural + (trueSpawnedCount == 1 ? '' : 's'),
61+ promise: rawSpawnedPointsPromise,
62+ points: spawnedPoints,
63+ count: trueSpawnedCount,
64+ };
65+ $: lockedTab = {
66+ name: 'Locked',
67+ plural: 'Locked ' + spawnableClassPlural + (lockedPoints.length == 1 ? '' : 's'),
68+ promise: rawLockedPointsPromise,
69+ points: lockedPoints,
70+ count: lockedPoints.length,
71+ };
72+ $: moons = filterIdsForChildMoons($store.peers, patp).map(patpToShip);
73+ $: moonsTab = {
74+ name: 'Moons',
75+ plural: 'Known Moon' + (moons.length == 1 ? '' : 's'),
76+ promise: true,
77+ points: moons,
78+ count: moons.length,
79+ };
80+ let tabIndex = 0;
81+ let tabs = [];
82+ $: {
83+ tabs = [];
84+ if (spawnedCount !== undefined || spawnedPoints.length > 0) {
85+ tabs.push(spawnedTab);
86+ }
87+ if (lockedPoints.length > 0) {
88+ tabs.push(lockedTab);
89+ }
90+ if (azPoint) {
91+ tabs.push(moonsTab);
92+ }
93+ }
94+ $: tab = tabs[tabIndex];
95+
96+ function patpToShip(id: string) {
97+ return { patp: normalizeId(id) };
98+ }
99+</script>
100+
101+<div class="p-3">
102+ {#if tabs.length > 1}
103+ <div class="flex gap-x-1">
104+ {#each tabs as tab, i}
105+ <h3 on:click={() => tabIndex = i}
106+ class:bg-gray-200={tabIndex !== i}
107+ class="px-2 border border-gray-300 border-b-0 rounded-t-md cursor-pointer"
108+ >
109+ {tab.name}
110+ </h3>
111+ {/each}
112+ </div>
113+ {/if}
114+ {#if tab}
115+ <div>
116+ <h3 class="text-lg m-2">
117+ {#if tab.count}
118+ {tab.count} {tab.plural}:
119+ {:else}
120+ No {tab.plural}
121+ {/if}
122+ </h3>
123+ {#await tab.promise}
124+ Loading {tab.plural}...
125+ {:then}
126+ <!-- TODO: pagination -->
127+ <ShipListings
128+ ships={tab.points}
129+ linkToShips
130+ differentiateContacts
131+ />
132+ {/await}
133+ </div>
134+ {/if}
135+</div>
136+
ui/src/components/ship_view/ShipView.sveltenew file+130
@@ -0,0 +1,130 @@
1+<script lang="ts">
2+ import { clan, patp2dec } from 'urbit-ob';
3+
4+ import { cite, normalizeId } from 'lib/id';
5+ import { getPoint, getSpawnedPoints } from 'lib/api';
6+ import { generateParentChain, processPointInfo } from 'lib/ship';
7+ import Sigil from '@/common/Sigil.svelte';
8+ import GoldBadge from '@/common/GoldBadge.svelte';
9+ import TooltipAndDocLink from '@/common/TooltipAndDocLink.svelte';
10+ import ShipLink from '@/common/ShipLink.svelte';
11+ import ChartLink from '@/common/ChartLink.svelte';
12+ import EthAddressLink from '@/common/EthAddressLink.svelte';
13+ import LoadingSpinner from '@/common/LoadingSpinner.svelte';
14+ import CollapsibleContent from '@/CollapsibleContent.svelte';
15+ import ShipChain from './ShipChain.svelte';
16+ import AzimuthDetails from './AzimuthDetails.svelte';
17+ import ShipChildrenTabs from './ShipChildrenTabs.svelte';
18+ import ProfileShipViewExtension from '~/components/extensions/ProfileShipViewExtension.svelte';
19+ import PalsShipViewExtension from '@/pals/PalsShipViewExtension.svelte';
20+ import AppsShipViewExtension from '@/extensions/AppsShipViewExtension.svelte';
21+ // import GroupsShipViewExtension from '~/components/extensions/GroupsShipViewExtension.svelte';
22+
23+ export let patp: string;
24+
25+ let parentChain: any[];
26+ let rawPointInfoPromise: any;
27+ let rawPointInfo: any = null;
28+ let pointInfo: any = {};
29+
30+ $: shipClass = clan(patp);
31+ $: azPoint = ['galaxy', 'star', 'planet'].includes(shipClass);
32+ $: {
33+ parentChain = generateParentChain(patp);
34+ }
35+ $: {
36+ rawPointInfo = null;
37+ if (azPoint) {
38+ rawPointInfoPromise = getPoint(patp);
39+ rawPointInfoPromise.then((info) => {
40+ rawPointInfo = info;
41+ }).catch((error) => {
42+ rawPointInfo = { error };
43+ });
44+ }
45+ }
46+ $: {
47+ pointInfo = {};
48+ if (azPoint) {
49+ pointInfo = processPointInfo(rawPointInfo);
50+ }
51+ }
52+</script>
53+
54+<div class="p-8 max-w-md w-full rounded-lg bg-white flex flex-col md:max-w-2xl">
55+ <div class="flex flex-col items-center space-y-4 md:flex-row md:items-start md:space-x-8 md:space-y-0">
56+ <div class="w-full max-w-[256px] md:min-w-[256px] flex-shrink-0">
57+ <Sigil patp={patp} size={256} useNew />
58+ </div>
59+ <div class="grow w-full min-w-0">
60+ <h2 class="text-2xl text-center">
61+ <TooltipAndDocLink
62+ text="The ship's @p (click to learn more)"
63+ doc="patpee" class="inline"
64+ >
65+ {cite(patp)}
66+ </TooltipAndDocLink>
67+ </h2>
68+ {#if (!azPoint)}
69+ <h3 class="text-lg text-center text-gray-700">{patp}</h3>
70+ {/if}
71+ <h4 class="text-center text-gray-700 break-words">
72+ {patp2dec(patp)}
73+ </h4>
74+ <div class="flex flex-wrap justify-center gap-1.5 my-1.5">
75+ <GoldBadge title={"it's a " + shipClass} doc={shipClass}>{shipClass}</GoldBadge>
76+ {#if azPoint}
77+ {#if pointInfo.spawnStatus}
78+ <GoldBadge title={pointInfo.spawnStatus.tooltip}>
79+ {pointInfo.spawnStatus.text}
80+ </GoldBadge>
81+ {/if}
82+ {#if pointInfo.layer}
83+ <GoldBadge title={pointInfo.layer.tooltip} doc="l2">{pointInfo.layer.text}</GoldBadge>
84+ {/if}
85+ {:else if (shipClass === 'moon')}
86+ <span>of</span>
87+ <ShipLink patp={parentChain.at(-1)}></ShipLink>
88+ {:else if (shipClass === 'comet')}
89+ <span>under</span>
90+ <ShipLink patp={parentChain.at(-1)}></ShipLink>
91+ {/if}
92+ </div>
93+ {#if pointInfo?.spawnedUnlocked}
94+ <div class="w-full text-center my-3">
95+ <ChartLink {patp}>View in Star Chart ↗</ChartLink>
96+ </div>
97+ {/if}
98+ <div class="mt-4 w-full break-words">
99+ {#if parentChain.length > 0}
100+ <p>
101+ {parentChain.length === 1 ? 'Parent:' : 'Parent Chain:'}
102+ <ShipChain shipChain={parentChain}></ShipChain>
103+ </p>
104+ {/if}
105+ {#if azPoint}
106+ {#await rawPointInfoPromise}
107+ <LoadingSpinner spinnerClass="text-black" />
108+ {:then}
109+ <CollapsibleContent>
110+ <b slot="title">Azimuth Details</b>
111+ <div slot="content">
112+ <AzimuthDetails {patp} {pointInfo}></AzimuthDetails>
113+ </div>
114+ </CollapsibleContent>
115+ {/await}
116+ {/if}
117+ </div>
118+ </div>
119+ </div>
120+ <div class="flex flex-wrap shrink min-h-0 h-fit -m-1 mt-2 justify-evenly justify-items-center">
121+ <ProfileShipViewExtension {patp} />
122+ <PalsShipViewExtension {patp} />
123+ <AppsShipViewExtension {patp} />
124+ </div>
125+ {#if azPoint}
126+ <div class="mt-5 border-t">
127+ <ShipChildrenTabs {patp} />
128+ </div>
129+ {/if}
130+</div>
ui/src/lib/api.ts+100−2
@@ -1,4 +1,102 @@
11import UrbitApi from '@urbit/http-api';
2−const api: UrbitApi = new UrbitApi('');
2+import type { ContactUpdate, Patp, Group, Contact, Rolodex } from '@urbit/api';
3+import _get from 'lodash/get';
4+import { compose } from 'lodash/fp';
35
4−export default api;
6+import { normalizeId } from './id';
7+
8+console.log(`Initializing Urbit API at ${Date()}`);
9+const api: UrbitApi = new UrbitApi('', '', window.desk);
10+api.ship = window.ship;
11+// api.connect();
12+
13+export { api };
14+
15+export function scry<T = any>(path: string): Promise<T> {
16+ return api.scry<T>({ app: 'astrolabe', path });
17+}
18+
19+export function getPoint(patp: string): Promise<any> {
20+ return scry<any>(`/point/${patp}`);
21+}
22+
23+export function getSpawnedPoints(patp: string): Promise<any> {
24+ return scry<any>(`/point/${patp}/spawned`);
25+}
26+
27+export function getLockedSpawnedPoints(patp: string): Promise<any> {
28+ return scry<any>(`/point/${patp}/spawned/locked`);
29+}
30+
31+export function getUnlockedSpawnedPoints(patp: string): Promise<any> {
32+ return scry<any>(`/point/${patp}/spawned/unlocked`);
33+}
34+
35+export function getPeers(): Promise<any> {
36+ return scry<any>(`/peers`);
37+}
38+
39+export async function searchPoints(search: string, mode: ('patp' | 'sigil')): Promise<Patp[]> {
40+ const { points } = await scry<any>(`/search/${mode}/${search}`);
41+ return points.map(normalizeId);
42+}
43+
44+export function getChartData(old = false): Promise<any> {
45+ return scry<any>('/chart-data' + (old ? '-old' : ''));
46+}
47+
48+window['gcd'] = getChartData;
49+
50+export function getDoc(path: string): Promise<string> {
51+ return scry<string>(`/doc/${path}`);
52+}
53+
54+export function initialContacts(json: ContactUpdate, contacts: Rolodex): Rolodex {
55+ const data = _get(json, 'initial', false);
56+ if (data) {
57+ contacts = data.rolodex;
58+ }
59+ return contacts;
60+};
61+
62+export function addContact(json: ContactUpdate, contacts: Rolodex): Rolodex {
63+ const data = _get(json, 'add', false);
64+ if (data) {
65+ contacts[data.ship] = data.contact;
66+ }
67+ return contacts;
68+};
69+
70+export function removeContact(json: ContactUpdate, contacts: Rolodex): Rolodex {
71+ const data = _get(json, 'remove', false);
72+ if (
73+ data &&
74+ (data.ship in contacts)
75+ ) {
76+ delete contacts[data.ship];
77+ }
78+ return contacts;
79+};
80+
81+export function handleContactUpdateEvent(updateContacts) {
82+ return ({ 'contact-update': contactUpdate }) => {
83+ console.log(`received contact-update: ${Object.keys(contactUpdate)}`)
84+ const reducers = [initialContacts, addContact, removeContact];
85+ const reducer = compose(reducers.map(r => sta => r(contactUpdate, sta)));
86+ updateContacts(reducer);
87+ };
88+}
89+
90+export function subscribeToContacts(e: (data: any) => void): Promise<any> {
91+ return api.subscribe({
92+ app: 'contact-store',
93+ path: '/all',
94+ event: handleContactUpdateEvent(e),
95+ err: () => {
96+ console.error(`Subscription to contact-store/all just get "err"`);
97+ },
98+ quit: () => {
99+ console.error(`Subscription to contact-store/all just get "quit"`);
100+ }
101+ })
102+}
ui/src/lib/apps.tsnew file+177

This diff is too big to show here.

ui/src/lib/colors.tsnew file+17

This diff is too big to show here.

ui/src/lib/graph.tsnew file+422

This diff is too big to show here.

ui/src/lib/id.ts+35−6

This diff is too big to show here.

ui/src/lib/link.ts+15−2

This diff is too big to show here.

ui/src/lib/pals.tsnew file+91

This diff is too big to show here.

ui/src/lib/ship.tsnew file+114

This diff is too big to show here.

ui/src/lib/sigil.tsnew file+387

This diff is too big to show here.

ui/src/lib/utils.ts+49−8

This diff is too big to show here.

ui/src/main.ts+5−2

This diff is too big to show here.

ui/src/routes/HelpPage.sveltenew file+26

This diff is too big to show here.

ui/src/routes/Home.svelte+191−7

This diff is too big to show here.

ui/src/routes/ShipViewPage.sveltedeleted−44

This diff is too big to show here.

ui/src/routes/SigilPage.sveltenew file+61

This diff is too big to show here.

ui/src/stores/docs.tsnew file+44

This diff is too big to show here.

ui/src/stores/keys.tsnew file+68

This diff is too big to show here.

ui/src/stores/pageName.tsnew file+12

This diff is too big to show here.

ui/src/stores/searchStores.tsnew file+66

This diff is too big to show here.

ui/src/stores/store.ts+59−48

This diff is too big to show here.

ui/src/styles/docs.scss+20−4

This diff is too big to show here.

ui/src/styles/styles.scss+4−2

This diff is too big to show here.

ui/src/styles/tailwind-output.css+1236−87

This diff is too big to show here.

ui/src/types/sigil.tsnew file+148

This diff is too big to show here.

ui/src/types/store.ts+60−3

This diff is too big to show here.

ui/svelte.config.js+2−2

This diff is too big to show here.

ui/tailwind.config.cjs+23−1

This diff is too big to show here.

ui/tsconfig.json+9

This diff is too big to show here.

ui/vite.config.ts+22−2

This diff is too big to show here.