From 7f8cd93f61c68ee2bf8ada2298f5d5eae58ab1e8 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Fri, 15 Dec 2023 00:55:41 +0100 Subject: [PATCH 001/138] 2023/12/14 --- .gitmodules | 3 +++ src/@orbitmines/external/github.com/akissinger/chyp | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 src/@orbitmines/external/github.com/akissinger/chyp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..df36d3d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/@orbitmines/external/github.com/akissinger/chyp"] + path = src/@orbitmines/external/github.com/akissinger/chyp + url = git@github.com:akissinger/chyp.git diff --git a/src/@orbitmines/external/github.com/akissinger/chyp b/src/@orbitmines/external/github.com/akissinger/chyp new file mode 160000 index 0000000..da4161c --- /dev/null +++ b/src/@orbitmines/external/github.com/akissinger/chyp @@ -0,0 +1 @@ +Subproject commit da4161c3145270f7d5f54138930d3e50a66028fc From 30de7a0b52ba3a93f15192d60b31bb2797f4bbb2 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 3 Jan 2024 00:16:24 +0100 Subject: [PATCH 002/138] 2024/02/02 - Setting up some stuff for Chyp --- package-lock.json | 386 ++++++++++++++++++ package.json | 3 + src/@orbitmines/README.md | 2 +- src/@orbitmines/explorer/Ray.ts | 26 +- src/@orbitmines/explorer/errors/errors.ts | 1 + .../external/implementations/chyp/Chyp.ts | 316 ++++++++++++++ .../external/implementations/chyp/Chyp.tsx | 23 ++ src/App.tsx | 11 +- src/lib/organizations/ORGANIZATIONS.ts | 9 + src/lib/organizations/akissinger/881183.png | Bin 0 -> 27009 bytes src/lib/paper/layout/Organization.tsx | 4 +- useless_junk/generate_chyp.js | 130 ++++++ 12 files changed, 894 insertions(+), 17 deletions(-) create mode 100644 src/@orbitmines/explorer/errors/errors.ts create mode 100644 src/@orbitmines/external/implementations/chyp/Chyp.ts create mode 100644 src/@orbitmines/external/implementations/chyp/Chyp.tsx create mode 100644 src/lib/organizations/akissinger/881183.png create mode 100644 useless_junk/generate_chyp.js diff --git a/package-lock.json b/package-lock.json index a7cddc2..72bd891 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,9 @@ "react-dev-utils": "^12.0.1", "schema-dts": "^1.1.2", "schema-dts-gen": "^1.1.2", + "tree-sitter": "^0.20.6", + "tree-sitter-python": "^0.20.4", + "tree-sitter-typescript": "^0.20.3", "typescript": "^5.0.4" } }, @@ -5804,6 +5807,55 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -6326,6 +6378,12 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -7391,11 +7449,35 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -7497,6 +7579,15 @@ "webgl-constants": "^1.1.1" } }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -7846,6 +7937,15 @@ "node": ">= 0.8" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -8698,6 +8798,15 @@ "node": ">= 0.8.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/expect": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", @@ -9199,6 +9308,12 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -9343,6 +9458,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -13127,6 +13248,18 @@ "node": ">= 0.6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mini-css-extract-plugin": { "version": "2.7.6", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", @@ -13224,6 +13357,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -13282,6 +13421,18 @@ "three": ">=0.137" } }, + "node_modules/nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "dev": true + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -13314,6 +13465,51 @@ "tslib": "^2.0.3" } }, + "node_modules/node-abi": { + "version": "3.52.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.52.0.tgz", + "integrity": "sha512-JJ98b02z16ILv7859irtXn4oUaFWADtvkzy2c0IAatNVX2Mc9Yoh8z6hZInn3QwvMEYhHuQloYi+TTQy67SIdQ==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -15317,6 +15513,32 @@ "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==" }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -15493,6 +15715,16 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -15625,6 +15857,30 @@ "node": ">=0.10.0" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -17023,6 +17279,51 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -17913,6 +18214,48 @@ "node": ">=6" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", @@ -18209,6 +18552,37 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/tree-sitter": { + "version": "0.20.6", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.6.tgz", + "integrity": "sha512-GxJodajVpfgb3UREzzIbtA1hyRnTxVbWVXrbC6sk4xTMH5ERMBJk9HJNq4c8jOJeUaIOmLcwg+t6mez/PDvGqg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "nan": "^2.18.0", + "prebuild-install": "^7.1.1" + } + }, + "node_modules/tree-sitter-python": { + "version": "0.20.4", + "resolved": "https://registry.npmjs.org/tree-sitter-python/-/tree-sitter-python-0.20.4.tgz", + "integrity": "sha512-F+94q/t9+4J5yaQnmfAqEf4OZFjuhuyniRtb9P2jPaBwHrbyJL44RKFALovZxhF0syLFKpTQ7ODywyiGeB1YMg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "nan": "^2.17.0" + } + }, + "node_modules/tree-sitter-typescript": { + "version": "0.20.3", + "resolved": "https://registry.npmjs.org/tree-sitter-typescript/-/tree-sitter-typescript-0.20.3.tgz", + "integrity": "sha512-5+RZ9G3/VOxxSzyniVc5dfNhfan1eOxQvUdTgXhpsGIYlmSW3HwIuPEJ7r65FWH2WnJWirOu11Pm0usmkx2JOg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "nan": "^2.14.0" + } + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -18326,6 +18700,18 @@ "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", "dev": true }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index d1e3b56..c3f43cf 100755 --- a/package.json +++ b/package.json @@ -42,6 +42,9 @@ "react-dev-utils": "^12.0.1", "schema-dts": "^1.1.2", "schema-dts-gen": "^1.1.2", + "tree-sitter": "^0.20.6", + "tree-sitter-python": "^0.20.4", + "tree-sitter-typescript": "^0.20.3", "typescript": "^5.0.4" }, "scripts": { diff --git a/src/@orbitmines/README.md b/src/@orbitmines/README.md index 57c5329..51c6d99 100644 --- a/src/@orbitmines/README.md +++ b/src/@orbitmines/README.md @@ -1,6 +1,6 @@ ![orbitmines.logo.3000x1000.png](..%2Flib%2Forganizations%2Forbitmines%2Flogo%2Forbitmines.logo.3000x1000.png) -# OrbitMines Explorer +# OrbitMines *An explorational interface.* --- diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 9e9d775..b576d82 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -211,19 +211,19 @@ export class Ray async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } // JS.Generator *[Symbol.iterator](): Generator { yield *this.traverse(); } - // JS.AsyncGenerator - as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); - // JS.AsyncIterator - as_async_iterator = (): AsyncIterator => this.as_async_generator(); - // JS.Iterator - as_generator = (): Generator => this[Symbol.iterator](); - // JS.AsyncIterator - as_iterator = (): Iterator => this.as_generator(); - // JS.Array - as_array = (): any[] => [...this]; - // JS.String - toString = (): string => this.as_array().toString(); - as_string = () => this.toString(); + // JS.AsyncGenerator + as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); + // JS.AsyncIterator + as_async_iterator = (): AsyncIterator => this.as_async_generator(); + // JS.Iterator + as_generator = (): Generator => this[Symbol.iterator](); + // JS.AsyncIterator + as_iterator = (): Iterator => this.as_generator(); + // JS.Array + as_array = (): any[] => [...this]; + // JS.String + toString = (): string => this.as_array().toString(); + as_string = () => this.toString(); /** * Quick dirty compilation diff --git a/src/@orbitmines/explorer/errors/errors.ts b/src/@orbitmines/explorer/errors/errors.ts new file mode 100644 index 0000000..55688dc --- /dev/null +++ b/src/@orbitmines/explorer/errors/errors.ts @@ -0,0 +1 @@ +export class NotImplementedError extends Error {} diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts new file mode 100644 index 0000000..d3a0b02 --- /dev/null +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -0,0 +1,316 @@ + +export type int = any; +export type list = any; +export type Iterable = any; +export type set = any; +export type str = any; +export type QKeyEvent = any; +export type Optional = any; +export type Tuple = any; +export type QObject = any; +export type Union = any; +export type QModelIndex = any; +export type QPersistentModelIndex = any; +export type QWidget = any; +export type List = any; +export type Qt = any; +export type Orientation = any; +export type QPainter = any; +export type QStyleOptionGraphicsItem = any; +export type bool = any; +export type QGraphicsSceneMouseEvent = any; +export type QTextDocument = any; +export type editor = any; +export type QCloseEvent = any; +export type Any = any; +export type tuple = any; +export type None = any; +export type state = any; +export type Callable = any; +export type Set = any; + +export type GraphError = { +} + +export type VData = { + __init__(): any; +} + +export type EData = { + __init__(): any; + __repr__(): any; + box_size(): any; +} + +export type Graph = { + __init__(): any; + copy(): any; + vertices(): any; + edges(): any; + num_vertices(): any; + num_edges(): any; + domain(): any; + codomain(): any; + vertex_data(v: int): any; + edge_data(e: int): any; + edge_domain(edge_id: int): any; + edge_codomain(edge_id: int): any; + in_edges(v: int): any; + out_edges(v: int): any; + source(e: int): any; + target(e: int): any; + add_vertex(): any; + add_edge(s: list, t: list): any; + remove_vertex(v: int): any; + remove_edge(e: int): any; + add_inputs(inp: list): any; + add_outputs(outp: list): any; + set_inputs(inp: list): any; + set_outputs(outp: list): any; + inputs(): any; + outputs(): any; + is_input(v: int): any; + is_output(v: int): any; + is_boundary(v: int): any; + successors(vs: Iterable): any; + merge_vertices(v: int, w: int): any; + explode_vertex(v: int): any; + insert_id_after(v: int): any; + tensor(other: Graph): any; + __mul__(other: Graph): any; + compose(other: Graph): any; + __rshift__(other: Graph): any; + highlight(vertices: set, edges: set): any; + unhighlight(): any; +} + +export type Chyp = { + __init__(): any; +} + +export type CodeView = { + __init__(): any; + popup_visible(): any; + set_completions(completions: Iterable): any; + ident_at_cursor(): any; + insert_completion(completion: str): any; + keyPressEvent(e: QKeyEvent): any; + set_current_region(region: Optional>): any; + add_line_below(text: str): any; +} + +export type CodeCompletionModel = { + __init__(parent: QObject): any; + set_completions(completions: Iterable): any; + data(index: Union): any; + rowCount(): any; +} + +export type ChypDocument = { + __init__(parent: QWidget): any; + confirm_close(): any; + add_to_recent_files(file_name: str): any; + open(file_name: str): any; + save(): any; + save_as(): any; +} + +export type Editor = { + __init__(): any; + title(): any; + reset_state(): any; + invalidate_text(): any; + next_part(): any; + jump_to_error(): any; + show_errors(): any; + show_at_cursor(): any; + next_rewrite_at_cursor(): any; + repeat_step_at_cursor(): any; + update_state(): any; + import_at_cursor(): any; +} + +export type CheckThread = { + __init__(rw: RewriteState): any; + run(): any; +} + +export type ErrorListModel = { + __init__(): any; + set_errors(errors: List>): any; + data(index: Union): any; + headerData(section: int, orientation: Orientation): any; + index(row: int, column: int): any; + columnCount(): any; + rowCount(): any; + parent(): any; +} + +export type EItem = { + __init__(g: Graph, e: int): any; + paint(painter: QPainter, option: QStyleOptionGraphicsItem): any; +} + +export type VItem = { + __init__(g: Graph, v: int): any; + refresh(): any; +} + +export type TItem = { + __init__(vitem: VItem, eitem: EItem, i: int, src: bool): any; + refresh(): any; +} + +export type GraphScene = { + __init__(): any; + set_graph(g: Graph): any; + add_items(): any; + mousePressEvent(e: QGraphicsSceneMouseEvent): any; + mouseMoveEvent(e: QGraphicsSceneMouseEvent): any; + mouseReleaseEvent(_: QGraphicsSceneMouseEvent): any; +} + +export type GraphView = { + __init__(): any; + set_graph(g: Graph): any; +} + +export type ChypHighlighter = { + __init__(doc: QTextDocument): any; + set_current_region(region: Optional>, status: int): any; + highlightBlock(text: str): any; +} + +export type MainWindow = { + __init__(): any; + remove_empty_editor(): any; + update_file_name(): any; + tab_changed(i: int): any; + update_themes(): any; + recent_files(): any; + update_recent_files(): any; + add_tab(ed: Editor, title: str): any; + close_tab(): any; + new(): any; + open(): any; + save(): any; + save_as(): any; + undo(): any; + redo(): any; + show_errors(): any; + add_rewrite_step(): any; + repeat_rewrite_step(): any; + next_rewrite(): any; + next_part(): any; + previous_part(): any; + next_tab(): any; + previous_tab(): any; + goto_import(): any; + closeEvent(e: QCloseEvent): any; + build_menu(): any; +} + +export type Match = { + __init__(): any; + __str__(): any; + copy(): any; + try_add_vertex(domain_vertex: int, codomain_vertex: int): any; + try_add_edge(domain_edge: int, codomain_edge: int): any; + domain_neighbourhood_mapped(vertex: int): any; + map_scalars(): any; + more(): any; + is_total(): any; + is_surjective(): any; + is_injective(): any; + is_convex(): any; +} + +export type Matches = { + __init__(domain: Graph, codomain: Graph): any; + __iter__(): any; + __next__(): any; +} + +export type RuleError = { +} + +export type Rule = { + __init__(lhs: Graph, rhs: Graph): any; + copy(): any; + converse(): any; + is_left_linear(): any; +} + +export type RewriteState = { + __init__(sequence: int, state: State): any; + check(): any; +} + +export type State = { + __init__(): any; + part_with_index_at(pos: int): any; + part_at(pos: int): any; + var(items: List): any; + module_name(items: List): any; + num(items: List): any; + type_element(items: list): any; + type_term(items: list | None>): any; + id(items: list): any; + id0(_: List): any; + eq(_: List): any; + le(_: List): any; + perm_indices(items: list): any; + size_list(items: list): any; + par(items: List): any; + gen_color(items: List): any; + color(items: List): any; + import_let(items: List): any; + tactic(items: List): any; + nested_term(items: List): any; +} + +export type Tactic = { + __init__(local_state: RewriteState, args: List): any; + repeat(rw: Callable, rules: List): any; + error(message: str): any; + has_goal(): any; + global_rules(): any; + lookup_rule(rule_expr: str): any; + add_refl_to_context(graph: Graph, ident: str): any; + add_rule_to_context(rule_name: str): any; + __lhs(target: str): any; + __rhs(target: str): any; + __set_lhs(target: str, graph: Graph): any; + __set_rhs(target: str, graph: Graph): any; + rewrite_lhs(rule_expr: str): any; + rewrite_rhs(rule_expr: str): any; + rewrite_lhs1(rule_expr: str): any; + rewrite_rhs1(rule_expr: str): any; + validate_goal(): any; + lhs(): any; + rhs(): any; + lhs_size(): any; + rhs_size(): any; + highlight_lhs(vertices: Set, edges: Set): any; + highlight_rhs(vertices: Set, edges: Set): any; + __reset(): any; + next_rhs(current: str): any; + run_check(): any; + name(): any; + check(): any; + make_rhs(): any; +} + +export type RuleTac = { + name(): any; + make_rhs(): any; + check(): any; +} + +export type SimpTac = { + name(): any; + __prepare_rules(): any; + make_rhs(): any; + check(): any; +} + diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.tsx b/src/@orbitmines/external/implementations/chyp/Chyp.tsx new file mode 100644 index 0000000..ffdb7b3 --- /dev/null +++ b/src/@orbitmines/external/implementations/chyp/Chyp.tsx @@ -0,0 +1,23 @@ +import {Row} from "../../../../lib/layout/flexbox"; +import Organization from "../../../../lib/paper/layout/Organization"; +import React from "react"; +import ORGANIZATIONS from "../../../../lib/organizations/ORGANIZATIONS"; + + +const Chyp = ( + // { + // listeners = [], + // }: { + // listeners?: IEventListener[], + // } +) => { + + return
+ {/**/} + {/* */} + {/* */} + {/**/} +
+} + +export default Chyp; \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index b9196a5..6e1a33c 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,6 +12,7 @@ import Legacy from "./lib/layout/experimental-designs/Legacy"; import BlueprintJS from "./lib/layout/experimental-designs/BlueprintJS"; import Modules from "./@orbitmines/js/react/Modules"; import Icons from "./lib/layout/experimental-designs/Icons"; +import Chyp from "./@orbitmines/external/implementations/chyp/Chyp"; export const Router = () => { @@ -20,11 +21,19 @@ export const Router = () => { } /> - } /> } /> + + + + } /> + + + + } /> + } /> } /> } /> diff --git a/src/lib/organizations/ORGANIZATIONS.ts b/src/lib/organizations/ORGANIZATIONS.ts index d411ee4..32760ec 100755 --- a/src/lib/organizations/ORGANIZATIONS.ts +++ b/src/lib/organizations/ORGANIZATIONS.ts @@ -12,6 +12,7 @@ import ngi_icon from "././ngi/Logo-NGI_Icon-circle-NGI-rgb.png"; import santa_fe_icon from "././santa-fe-institute/0_OgRM7UU-SsqK46La.png"; import papers_we_love_icon from "././papers-we-love/6187757.png"; import wolfram_institute_icon from "././wolfram-institute/channels4_profile.jpg"; +import akissinger_icon from "././akissinger/881183.png"; import {Renderable} from "../typescript/React"; import {ReferenceProps} from "../paper/layout/Reference"; @@ -101,6 +102,14 @@ const ORGANIZATIONS = { icon_png: orbitmines_icon, } }, + chyp: { + key: 'chypr', + name: "chyp", + assets: { + logo: akissinger_icon, + icon_png: akissinger_icon, + } + }, semf: { key: 'semf', name: "SEMF", diff --git a/src/lib/organizations/akissinger/881183.png b/src/lib/organizations/akissinger/881183.png new file mode 100644 index 0000000000000000000000000000000000000000..706ba660582aec9c66931d81b7f9290563cc987f GIT binary patch literal 27009 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 literal 0 HcmV?d00001 diff --git a/src/lib/paper/layout/Organization.tsx b/src/lib/paper/layout/Organization.tsx index 5a7aa76..50fff67 100644 --- a/src/lib/paper/layout/Organization.tsx +++ b/src/lib/paper/layout/Organization.tsx @@ -5,7 +5,7 @@ import React from "react"; import {AllowReact} from "../../typescript/React"; import {TOrganization} from "../../organizations/ORGANIZATIONS"; -const Organization = (props: AllowReact) => { +const Organization = (props: AllowReact & { only_logo?: boolean }) => { const { name, assets } = props; const { logo } = assets; @@ -13,7 +13,7 @@ const Organization = (props: AllowReact) => { {_.isString(name) -

{name}

+ {props.only_logo ? <> :

{name}

} } diff --git a/useless_junk/generate_chyp.js b/useless_junk/generate_chyp.js new file mode 100644 index 0000000..4996d73 --- /dev/null +++ b/useless_junk/generate_chyp.js @@ -0,0 +1,130 @@ +const Parser = require('tree-sitter'); +const TypeScript = require('tree-sitter-typescript'); +const Python = require('tree-sitter-python'); +const fs = require("fs"); +const path = require('path'); +const _ = require("lodash"); + +const parser = new Parser(); +parser.setLanguage(Python); + +function getAllFilesSync(dir, fileList = []) { + const files = fs.readdirSync(dir); + + for (const file of files) { + const filePath = path.join(dir, file); + const stat = fs.statSync(filePath); + + if (stat.isDirectory()) { + getAllFilesSync(filePath, fileList); + } else { + if (path.extname(file) === '.py') { + fileList.push(filePath); + } + } + } + + return fileList; +} + +const files = getAllFilesSync("../src/@orbitmines/external/github.com/akissinger/chyp/chyp"); +console.log(files) + + +const classesAndMethods = []; + + +files.forEach(file => { + const source = fs.readFileSync(file, 'utf-8') + const tree = parser.parse(source); +// Traverse the AST to extract classes, methods, arguments, and return types + + tree.rootNode.children.forEach((node) => { + if (node.type === 'class_definition') { + const currentClass = { + name: node.firstChild.nextNamedSibling.text, + methods: [], + }; + + // Traverse class body for methods + node.lastChild.children.forEach((classChildNode) => { + if (classChildNode.type === 'function_definition') { + const method = { + name: classChildNode.firstChild.nextNamedSibling.text, + arguments: [], + returnType: 'any', // Default return type + }; + + // Traverse method parameters + classChildNode.firstChild.nextNamedSibling.nextSibling.children.forEach((paramNode) => { + + if (paramNode.type === 'typed_parameter') { + const paramName = paramNode.firstChild.text; + const paramTypeNode = paramNode.lastChild; + + // console.log(paramTypeNode.text) + + // Check if there is a type annotation + const paramType = paramTypeNode.text ?? 'any'; + + method.arguments.push({ name: paramName, type: paramType }); + } + }); + + // Check for return type annotation + const returnTypeNode = classChildNode.lastChild.firstChild; + if (returnTypeNode && returnTypeNode.type === 'typed_identifier') { + method.returnType = returnTypeNode.lastChild.text; + } + + currentClass.methods.push(method); + } + }); + + classesAndMethods.push(currentClass); + } + }); +}) +// Print the extracted information +console.log(JSON.stringify(classesAndMethods, null, 2)); + +function generateTypeScriptTypes(classesAndMethods) { + const typeScriptCode = []; + + classesAndMethods.forEach((classInfo) => { + typeScriptCode.push(`export type ${classInfo.name} = {`); + + classInfo.methods.forEach((method) => { + const params = method.arguments.map((arg) => `${arg.name}: ${ + _.last(arg.type + .replaceAll('[', '<') + .replaceAll(']', '>') + .replaceAll(/<(.*)>,/g, "$1[],") + .split('.')) + }`).join(', '); + typeScriptCode.push(` ${method.name}(${params}): ${method.returnType};`); + }); + + typeScriptCode.push('}\n'); + }); + + return typeScriptCode.join('\n'); +} + +// Assuming classesAndMethods is the result from the previous script +const typeScriptCode = ` +${_.uniq(classesAndMethods.flatMap(c => c.methods).flatMap(method => [method.returnType, ...method.arguments.map(arg => arg.type)]) + .flatMap(arg => arg.split(/[\[\],.|]/g)) + .map(arg => arg.trim()) + .filter(arg => arg !== '') +) + .filter(arg => arg !== 'any' && !classesAndMethods.map(c => c.name).includes(arg)) + .map(arg => `export type ${ + arg + } = any;`).join('\n')} + +${generateTypeScriptTypes(classesAndMethods)} +`; + + +fs.writeFileSync('../src/@orbitmines/external/implementations/chyp/Chyp.ts', typeScriptCode) \ No newline at end of file From 49b90002cfe31cfb8874f70a6fc320ee0bd0ab0e Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 3 Jan 2024 13:44:20 +0100 Subject: [PATCH 003/138] 2024/02/03 - Some helpers --- .../explorer/OrbitMinesExplorer.tsx | 105 +++++++++++++++++- src/@orbitmines/explorer/Ray.ts | 4 +- .../external/implementations/chyp/Chyp.tsx | 23 ---- .../implementations/chyp/ChypCanvas.tsx | 59 ++++++++++ src/App.tsx | 4 +- useless_junk/generate_chyp.js | 2 +- 6 files changed, 166 insertions(+), 31 deletions(-) delete mode 100644 src/@orbitmines/external/implementations/chyp/Chyp.tsx create mode 100644 src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index f251d90..9c32dc8 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -12,8 +12,9 @@ import {Option} from "../js/utils/Option"; import _ from "lodash"; import IEventListener, {mergeListeners} from "../js/react/IEventListener"; import {toJpeg, toPng} from "html-to-image"; -import {value} from "../../lib/typescript/React"; +import {Children, value} from "../../lib/typescript/React"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; +import {NotImplementedError} from "./errors/errors"; const add = (a: number[], b: number[]): [number, number, number] => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; @@ -94,6 +95,104 @@ const BinarySuperposition = ({ position }: any) => { } +/** + * Temporary Ray visualization till the visualization is incorporated into the editor (Basically when Visualization = Ray) + * + * TODO; Generalize to Ray - should be embedded on the vertex, or on another layer of description, where the interface is a rewrite rule + */ +type InterfaceOptions = { + position?: [number, number, number], + rotation?: [number, number, number], + scale?: number, + color?: string +} +type Options = { + initial?: InterfaceOptions, + vertex?: InterfaceOptions, + terminal?: InterfaceOptions, +} + +export const AutoRenderedRay = (ray: Omit & InterfaceOptions) => { + const _default: Required = { + position: [0, 0, 0], + rotation: [0, 0, 0], + scale: 1, + color: 'orange', + // ..._.pick(ray.vertex, 'position', 'rotation', 'scale', 'color'), + ..._.pick(ray, 'position', 'rotation', 'scale', 'color') + } + + const initial: Required = { ..._default, position: [-20 * _default.scale, 0, 0], ...ray.initial }; + + // Vertex as the origin for rotation + const vertex: Required = { ..._default, position: [0, 0, 0] } //, ...ray.vertex }; + const terminal: Required = { ..._default, position: [20 * _default.scale, 0, 0], ...ray.terminal }; + + const Group = ({ children }: Children) => { + return + {children} + + } + + return + + + + +} +export const SimpleRenderedRay = ( + ray: Pick + & Options // Relative options to other rays + & InterfaceOptions // Default options +) => { + const _default: Required = { + position: [0, 0, 0], + rotation: [0, 0, 0], + scale: 1, + color: 'orange', + ..._.pick(ray, 'position', 'rotation', 'scale', 'color') + } + + console.log(_default) + const _Continuation = ({ color = torus.color, ...options }: InterfaceOptions) => + + const _Vertex = ({ color = circle.color, ...options }: any) => + + + const initial: Required = { ..._default, ...ray.initial }; + const vertex: Required = { ..._default, ...ray.vertex }; + const terminal: Required = { ..._default, ...ray.terminal }; + const { type } = ray; + + switch (type) { + case RayType.REFERENCE: + throw new NotImplementedError(); + case RayType.INITIAL: { + return <> + + <_Continuation {...vertex} /> + + } + case RayType.TERMINAL: { + return <> + + <_Continuation {...vertex} /> + + } + case RayType.VERTEX: { + return <_Vertex {...vertex} /> + } + } +} + // In principle, this should be anything, this is just for the initial setup const RenderedRay = ( props: { reference: Option } & { position?: [number, number, number], scale?: number, } @@ -112,7 +211,7 @@ const RenderedRay = ( const Rendered = () => { - const type = vertex.as_reference().type(); + const type = vertex.as_reference().type; switch (type) { case RayType.INITIAL: { /** @@ -659,7 +758,7 @@ const Test2 = ({ ray, position }: { ray: Ray, position: [number, number, number] // * // */ // -// console.log('type:', reference.force().type()); +// console.log('type:', reference.force().type); // console.log('structure at', dereferenced.js().force()) // // console.log(' traversing nested reference'); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index b576d82..028a40c 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -191,7 +191,7 @@ export class Ray // TODO NEEDS TO CHECK IF THERE'S SOME INITIAL DEFIEND ; for defining if it has halted - type = (): RayType => { + get type(): RayType { if (this.is_reference()) return RayType.REFERENCE; if (this.is_initial()) @@ -249,7 +249,7 @@ export class Ray obj.initial = of(this.initial()); obj.vertex = of(this.vertex()); obj.terminal = of(this.terminal()); - obj.type = this.as_reference().type(); + obj.type = this.as_reference().type; return obj; } diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.tsx b/src/@orbitmines/external/implementations/chyp/Chyp.tsx deleted file mode 100644 index ffdb7b3..0000000 --- a/src/@orbitmines/external/implementations/chyp/Chyp.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import {Row} from "../../../../lib/layout/flexbox"; -import Organization from "../../../../lib/paper/layout/Organization"; -import React from "react"; -import ORGANIZATIONS from "../../../../lib/organizations/ORGANIZATIONS"; - - -const Chyp = ( - // { - // listeners = [], - // }: { - // listeners?: IEventListener[], - // } -) => { - - return
- {/**/} - {/* */} - {/* */} - {/**/} -
-} - -export default Chyp; \ No newline at end of file diff --git a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx new file mode 100644 index 0000000..bb4a488 --- /dev/null +++ b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx @@ -0,0 +1,59 @@ +import React from "react"; +import IEventListener, {mergeListeners} from "../../../js/react/IEventListener"; +import {VisualizationCanvas} from "../../../explorer/Visualization"; +import {AutoRenderedRay, SimpleRenderedRay} from "../../../explorer/OrbitMinesExplorer"; +import {RayType} from "../../../explorer/Ray"; + + +const ChypCanvas = ( + { + listeners = [], + }: { + listeners?: IEventListener[], + } +) => { + const listener: IEventListener = { + + } + + const scale = 1.5; + + return
+ {/**/} + {/* */} + {/* */} + {/**/} + + + + + + + + + + + +
+} + +export const ChypExplorer = ( + { + listeners = [], + }: { + listeners?: IEventListener[], + } +) => { + + const listener: IEventListener = { + + } + + return +} + +export default ChypCanvas; \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 6e1a33c..32528b8 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,7 +12,7 @@ import Legacy from "./lib/layout/experimental-designs/Legacy"; import BlueprintJS from "./lib/layout/experimental-designs/BlueprintJS"; import Modules from "./@orbitmines/js/react/Modules"; import Icons from "./lib/layout/experimental-designs/Icons"; -import Chyp from "./@orbitmines/external/implementations/chyp/Chyp"; +import ChypCanvas, {ChypExplorer} from "./@orbitmines/external/implementations/chyp/ChypCanvas"; export const Router = () => { @@ -27,7 +27,7 @@ export const Router = () => { - } /> + } /> diff --git a/useless_junk/generate_chyp.js b/useless_junk/generate_chyp.js index 4996d73..905ff80 100644 --- a/useless_junk/generate_chyp.js +++ b/useless_junk/generate_chyp.js @@ -127,4 +127,4 @@ ${generateTypeScriptTypes(classesAndMethods)} `; -fs.writeFileSync('../src/@orbitmines/external/implementations/chyp/Chyp.ts', typeScriptCode) \ No newline at end of file +fs.writeFileSync('../src/@orbitmines/external/implementations/chyp/ChypCanvas.ts', typeScriptCode) \ No newline at end of file From 947dfcec74f43c8a819c6e4e48757368ff5e2e6f Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 4 Jan 2024 13:02:07 +0100 Subject: [PATCH 004/138] 2024/02/04 - Some helpers --- .../explorer/OrbitMinesExplorer.tsx | 12 ++++++++- .../implementations/chyp/ChypCanvas.tsx | 27 ++++++++++++++----- src/lib/paper/Paper.tsx | 27 ++++++++++++++++--- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index dd98b94..f4fe695 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -213,7 +213,12 @@ type Options = { terminal?: InterfaceOptions, } -export const AutoRenderedRay = (ray: Omit & InterfaceOptions) => { +export const AutoRenderedRay = (ray: Omit & InterfaceOptions & { + length?: number // basically .length +}) => { + const { + length = 1 + } = ray; const _default: Required = { position: [0, 0, 0], rotation: [0, 0, 0], @@ -229,6 +234,11 @@ export const AutoRenderedRay = (ray: Omit & InterfaceOptions) const vertex: Required = { ..._default, position: [0, 0, 0] } //, ...ray.vertex }; const terminal: Required = { ..._default, position: [20 * _default.scale, 0, 0], ...ray.terminal }; + + if (length > 1) // TODO, currently rotates around each vertex individually + return {[...Array(length)] + .map(((_, i) => ))} + const Group = ({ children }: Children) => { return {children} diff --git a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx index bb4a488..c1b0d5d 100644 --- a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx @@ -3,6 +3,7 @@ import IEventListener, {mergeListeners} from "../../../js/react/IEventListener"; import {VisualizationCanvas} from "../../../explorer/Visualization"; import {AutoRenderedRay, SimpleRenderedRay} from "../../../explorer/OrbitMinesExplorer"; import {RayType} from "../../../explorer/Ray"; +import {Center} from "@react-three/drei"; const ChypCanvas = ( @@ -29,13 +30,25 @@ const ChypCanvas = ( {...mergeListeners(...listeners, listener)} > - - - - - - - +
+ + + + + + + + + + + + +
+ {/**/} + {/**/} + {/**/} + {/**/} + {/**/} diff --git a/src/lib/paper/Paper.tsx b/src/lib/paper/Paper.tsx index 5c501da..ac80041 100644 --- a/src/lib/paper/Paper.tsx +++ b/src/lib/paper/Paper.tsx @@ -10,7 +10,11 @@ import {Grid, Row} from "../layout/flexbox"; import {Center} from "@react-three/drei"; import {Continuation, Loop, RenderedRay, torus, Vertex} from "../../@orbitmines/explorer/OrbitMinesExplorer"; import {length} from "../../@orbitmines/explorer/Ray"; -import {CachedVisualizationCanvas, VisualizationCanvas} from "../../@orbitmines/explorer/Visualization"; +import { + CachedVisualizationCanvas, + CanvasContainer, + VisualizationCanvas +} from "../../@orbitmines/explorer/Visualization"; import JetBrainsMono from "../layout/font/fonts/JetBrainsMono/JetBrainsMono"; import {ON_ORBITS} from "../../routes/papers/2023.OnOrbits"; import ORGANIZATIONS from "../organizations/ORGANIZATIONS"; @@ -47,12 +51,14 @@ export const ThumbnailPage = () => { const title = params.get('title') ?? 'OrbitMines - Stream'; const subtitle = params.get('subtitle') ?? ''; + const date = params.get('date') ?? new Date().toISOString().split('T')[0]; const referenceCounter = useCounter(); const paper: Omit = { title, subtitle, + date, pdf: { fonts: [ JetBrainsMono ], }, @@ -69,7 +75,18 @@ export const ThumbnailPage = () => { }], draft: false, Reference: (props: {}) => (<>), - references: referenceCounter + references: referenceCounter, + header: + + } return
@@ -80,7 +97,7 @@ export const ThumbnailPage = () => { } export const PaperThumbnail = ( - {size, ...props}: PaperProps & { size?: { width: number, height: number } } + {size, header, ...props}: PaperProps & { size?: { width: number, height: number } } ) => { const [params] = useSearchParams(); @@ -97,7 +114,7 @@ export const PaperThumbnail = ( }}>
- + + {header}
From d4103c9f724541930e474743fa3ea070d5e771cf Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 4 Jan 2024 21:39:04 +0100 Subject: [PATCH 005/138] 2024/02/04 - Some initial translations of Chyp --- .../explorer/OrbitMinesExplorer.tsx | 17 +- src/@orbitmines/explorer/Ray.ts | 4 + .../external/implementations/chyp/Chyp.ts | 623 ++++++++++-------- .../external/implementations/chyp/Chyp2.ts | 317 +++++++++ .../implementations/chyp/ChypCanvas.tsx | 70 +- useless_junk/generate_chyp.js | 6 +- 6 files changed, 743 insertions(+), 294 deletions(-) create mode 100644 src/@orbitmines/external/implementations/chyp/Chyp2.ts diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index f4fe695..dd0b74a 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -144,7 +144,7 @@ const BinaryValue = ({ boolean, position }: any) => { } -export const BinarySuperposition = ({ position = [0, 0, 0] }: any) => { +export const BinarySuperposition = ({ position = [0, 0, 0], scale = 1.5 }: any) => { const halfTorus = (torus.radius + (torus.tube.width / 2)); const up = add(position, [0, 20 + halfTorus, 0]); @@ -174,18 +174,18 @@ export const BinarySuperposition = ({ position = [0, 0, 0] }: any) => { + ]} color="#FF5555" lineWidth={line.width * scale}/> + ]} color="#5555FF" lineWidth={line.width * scale}/> @@ -215,9 +215,10 @@ type Options = { export const AutoRenderedRay = (ray: Omit & InterfaceOptions & { length?: number // basically .length -}) => { +} & Partial) => { const { - length = 1 + length = 1, + children } = ray; const _default: Required = { position: [0, 0, 0], @@ -249,6 +250,8 @@ export const AutoRenderedRay = (ray: Omit & InterfaceOptions + + {children}
} export const SimpleRenderedRay = ( diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 2db76c0..55feceb 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -2,6 +2,7 @@ import {enumeration, MemberType, none, TaggedUnion} from "../../@orbitmines/js/u import {Option} from "../js/utils/Option"; import _ from "lodash"; import {compile} from "sass"; +import {NotImplementedError} from "./errors/errors"; export type ParameterlessFunction = () => T; @@ -202,6 +203,9 @@ export class Ray return RayType.VERTEX; } + count = (): Ray => { throw new NotImplementedError() } + copy = (): Ray => { throw new NotImplementedError() } + *traverse(): Generator {} /** diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index d3a0b02..7ea27e2 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -1,316 +1,417 @@ +import {JS, Ray} from "../../../explorer/Ray"; +import { NotImplementedError } from "../../../explorer/errors/errors"; +import {Option} from "../../../js/utils/Option"; -export type int = any; -export type list = any; -export type Iterable = any; -export type set = any; -export type str = any; -export type QKeyEvent = any; -export type Optional = any; -export type Tuple = any; -export type QObject = any; -export type Union = any; -export type QModelIndex = any; -export type QPersistentModelIndex = any; -export type QWidget = any; -export type List = any; -export type Qt = any; -export type Orientation = any; -export type QPainter = any; -export type QStyleOptionGraphicsItem = any; -export type bool = any; -export type QGraphicsSceneMouseEvent = any; -export type QTextDocument = any; -export type editor = any; -export type QCloseEvent = any; -export type Any = any; -export type tuple = any; -export type None = any; -export type state = any; -export type Callable = any; -export type Set = any; - -export type GraphError = { +/** + * Probably want all these types at runtime, to display them + */ + +export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; + +/** + * Non-default vertex types are identified by a string label + * + * str() | None() - No overloading in TypeScript ;( + */ +export const VType = JS.Iterable([str, None]); + +/** + * An error occurred in the graph backend. + * + * TODO probably hooked as a boolean, one successful the other not + */ +export class GraphError extends Ray { } -export type VData = { - __init__(): any; +/** + * Data associated with a single vertex. + */ +export class VData extends Ray { + + // The vertex type. + get vtype(): Ray { throw new NotImplementedError(); } + + /** + * The register size (number of bundled parallel wires) of the vertex. + * + * TODO: Just a counter over a line + */ + get size(): Ray { throw new NotImplementedError(); } + + /** + * Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). + */ + get infer_type(): Ray { throw new NotImplementedError(); } + + /** + * Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). + */ + get infer_size(): Ray { throw new NotImplementedError(); } + + + /** + * TODO: These coordinates used for inferences? + * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" + */ + + // x-coordinate at which to draw the vertex. + get x(): Ray { throw new NotImplementedError(); } + // y-coordinate at which to draw the vertex. + get y(): Ray { throw new NotImplementedError(); } + + // TODO: Just some boolean + get hightlight(): Ray { throw new NotImplementedError(); } + + __init__ = (): any => { throw new NotImplementedError(); } + } -export type EData = { - __init__(): any; - __repr__(): any; - box_size(): any; +export class EData extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } + __repr__ = (): any => { throw new NotImplementedError(); } + box_size = (): any => { throw new NotImplementedError(); } + + toString = (): string => this.__repr__(); } -export type Graph = { - __init__(): any; - copy(): any; - vertices(): any; - edges(): any; - num_vertices(): any; - num_edges(): any; - domain(): any; - codomain(): any; - vertex_data(v: int): any; - edge_data(e: int): any; - edge_domain(edge_id: int): any; - edge_codomain(edge_id: int): any; - in_edges(v: int): any; - out_edges(v: int): any; - source(e: int): any; - target(e: int): any; - add_vertex(): any; - add_edge(s: list, t: list): any; - remove_vertex(v: int): any; - remove_edge(e: int): any; - add_inputs(inp: list): any; - add_outputs(outp: list): any; - set_inputs(inp: list): any; - set_outputs(outp: list): any; - inputs(): any; - outputs(): any; - is_input(v: int): any; - is_output(v: int): any; - is_boundary(v: int): any; - successors(vs: Iterable): any; - merge_vertices(v: int, w: int): any; - explode_vertex(v: int): any; - insert_id_after(v: int): any; - tensor(other: Graph): any; - __mul__(other: Graph): any; - compose(other: Graph): any; - __rshift__(other: Graph): any; - highlight(vertices: set, edges: set): any; - unhighlight(): any; +/** + * A hypergraph with boundaries. + * + * This is the main data structure used by Chyp. It represents a directed + * hypergraph (which we call simply a "graph") as two dictionaries for + * vertices and (hyper)edges, respectively. Each vertex is associated with a + * `VData` object and edge edge with an `EData` object, which stores + * information about adjacency, position, label, etc. + * + * The particular flavor of hypergraphs we use associate to each hyperedge a + * list of source vertices and a list of target vertices. The hypergraph + * itself also has a list of input vertices and a list of output vertices, + * which are used for sequential composition and rewriting. + */ +export class Graph extends Ray { + + // Mapping from integer identifiers of each vertex to its data. + get vdata(): Ray { throw new NotImplementedError(); } + // Mapping from integer identifiers of each hyperedge to its data. + get edata(): Ray { throw new NotImplementedError(); } + + get vindex(): Ray { throw new NotImplementedError(); } + get eindex(): Ray { throw new NotImplementedError(); } + + __init__ = (): any => { throw new NotImplementedError(); } + + // Implemented on Ray + // copy = (): any => { throw new NotImplementedError(); } + + vertices = (): any => { throw new NotImplementedError(); } + edges = (): any => { throw new NotImplementedError(); } + num_vertices = (): any => { throw new NotImplementedError(); } + num_edges = (): any => { throw new NotImplementedError(); } + domain = (): any => { throw new NotImplementedError(); } + codomain = (): any => { throw new NotImplementedError(); } + vertex_data = (v = int): any => { throw new NotImplementedError(); } + edge_data = (e = int): any => { throw new NotImplementedError(); } + edge_domain = (edge_id = int): any => { throw new NotImplementedError(); } + edge_codomain = (edge_id = int): any => { throw new NotImplementedError(); } + in_edges = (v = int): any => { throw new NotImplementedError(); } + out_edges = (v = int): any => { throw new NotImplementedError(); } + source = (e = int): any => { throw new NotImplementedError(); } + target = (e = int): any => { throw new NotImplementedError(); } + add_vertex = (): any => { throw new NotImplementedError(); } + add_edge = (s = list(int), t = list(int)): any => { throw new NotImplementedError(); } + remove_vertex = (v = int): any => { throw new NotImplementedError(); } + remove_edge = (e = int): any => { throw new NotImplementedError(); } + add_inputs = (inp = list(int)): any => { throw new NotImplementedError(); } + add_outputs = (outp = list(int)): any => { throw new NotImplementedError(); } + set_inputs = (inp = list(int)): any => { throw new NotImplementedError(); } + set_outputs = (outp = list(int)): any => { throw new NotImplementedError(); } + // Return the list of vertex ids of the graph inputs. + inputs = (): any => { throw new NotImplementedError(); } + // Return the list of vertex ids of the graph outputs. + outputs = (): any => { throw new NotImplementedError(); } + _inputs = this.inputs; + _outputs = this.outputs; + is_input = (v = int): any => { throw new NotImplementedError(); } + is_output = (v = int): any => { throw new NotImplementedError(); } + is_boundary = (v = int): any => { throw new NotImplementedError(); } + successors = (vs = Iterable(int)): any => { throw new NotImplementedError(); } + merge_vertices = (v = int, w = int): any => { throw new NotImplementedError(); } + explode_vertex = (v = int): any => { throw new NotImplementedError(); } + insert_id_after = (v = int): any => { throw new NotImplementedError(); } + tensor = (other = Graph): any => { throw new NotImplementedError(); } + __mul__ = (other = Graph): any => { throw new NotImplementedError(); } + compose = (other = Graph): any => { throw new NotImplementedError(); } + __rshift__ = (other = Graph): any => { throw new NotImplementedError(); } + highlight = (vertices = set(int), edges = set(int)): any => { throw new NotImplementedError(); } + unhighlight = (): any => { throw new NotImplementedError(); } } -export type Chyp = { - __init__(): any; +export class Chyp extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } } -export type CodeView = { - __init__(): any; - popup_visible(): any; - set_completions(completions: Iterable): any; - ident_at_cursor(): any; - insert_completion(completion: str): any; - keyPressEvent(e: QKeyEvent): any; - set_current_region(region: Optional>): any; - add_line_below(text: str): any; +export class CodeView extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } + popup_visible = (): any => { throw new NotImplementedError(); } + set_completions = (completions = Iterable(str)): any => { throw new NotImplementedError(); } + ident_at_cursor = (): any => { throw new NotImplementedError(); } + insert_completion = (completion = str): any => { throw new NotImplementedError(); } + keyPressEvent = (e = QKeyEvent): any => { throw new NotImplementedError(); } + set_current_region = (region = Optional(Tuple(int,int))): any => { throw new NotImplementedError(); } + add_line_below = (text = str): any => { throw new NotImplementedError(); } } -export type CodeCompletionModel = { - __init__(parent: QObject): any; - set_completions(completions: Iterable): any; - data(index: Union): any; - rowCount(): any; +export class CodeCompletionModel extends Ray { + __init__ = (parent = QObject): any => { throw new NotImplementedError(); } + set_completions = (completions = Iterable(str)): any => { throw new NotImplementedError(); } + data = (index = Union(QModelIndex, QPersistentModelIndex)): any => { throw new NotImplementedError(); } + rowCount = (): any => { throw new NotImplementedError(); } } -export type ChypDocument = { - __init__(parent: QWidget): any; - confirm_close(): any; - add_to_recent_files(file_name: str): any; - open(file_name: str): any; - save(): any; - save_as(): any; +export class ChypDocument extends Ray { + __init__ = (parent = QWidget): any => { throw new NotImplementedError(); } + confirm_close = (): any => { throw new NotImplementedError(); } + add_to_recent_files = (file_name = str): any => { throw new NotImplementedError(); } + open = (file_name = str): any => { throw new NotImplementedError(); } + save = (): any => { throw new NotImplementedError(); } + save_as = (): any => { throw new NotImplementedError(); } } -export type Editor = { - __init__(): any; - title(): any; - reset_state(): any; - invalidate_text(): any; - next_part(): any; - jump_to_error(): any; - show_errors(): any; - show_at_cursor(): any; - next_rewrite_at_cursor(): any; - repeat_step_at_cursor(): any; - update_state(): any; - import_at_cursor(): any; +export class Editor extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } + title = (): any => { throw new NotImplementedError(); } + reset_state = (): any => { throw new NotImplementedError(); } + invalidate_text = (): any => { throw new NotImplementedError(); } + next_part = (): any => { throw new NotImplementedError(); } + jump_to_error = (): any => { throw new NotImplementedError(); } + show_errors = (): any => { throw new NotImplementedError(); } + show_at_cursor = (): any => { throw new NotImplementedError(); } + next_rewrite_at_cursor = (): any => { throw new NotImplementedError(); } + repeat_step_at_cursor = (): any => { throw new NotImplementedError(); } + update_state = (): any => { throw new NotImplementedError(); } + import_at_cursor = (): any => { throw new NotImplementedError(); } } -export type CheckThread = { - __init__(rw: RewriteState): any; - run(): any; +export class CheckThread extends Ray { + __init__ = (rw = RewriteState): any => { throw new NotImplementedError(); } + run = (): any => { throw new NotImplementedError(); } } -export type ErrorListModel = { - __init__(): any; - set_errors(errors: List>): any; - data(index: Union): any; - headerData(section: int, orientation: Orientation): any; - index(row: int, column: int): any; - columnCount(): any; - rowCount(): any; - parent(): any; +export class ErrorListModel extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } + set_errors = (errors = List(Tuple(str, int, str))): any => { throw new NotImplementedError(); } + data = (index = Union(QModelIndex, QPersistentModelIndex)): any => { throw new NotImplementedError(); } + headerData = (section = int, orientation = Orientation): any => { throw new NotImplementedError(); } + index = (row = int, column = int): any => { throw new NotImplementedError(); } + columnCount = (): any => { throw new NotImplementedError(); } + rowCount = (): any => { throw new NotImplementedError(); } + parent = (): any => { throw new NotImplementedError(); } } -export type EItem = { - __init__(g: Graph, e: int): any; - paint(painter: QPainter, option: QStyleOptionGraphicsItem): any; +export class EItem extends Ray { + __init__ = (g = Graph, e = int): any => { throw new NotImplementedError(); } + paint = (painter = QPainter, option = QStyleOptionGraphicsItem): any => { throw new NotImplementedError(); } } -export type VItem = { - __init__(g: Graph, v: int): any; - refresh(): any; +export class VItem extends Ray { + __init__ = (g = Graph, v = int): any => { throw new NotImplementedError(); } + refresh = (): any => { throw new NotImplementedError(); } } -export type TItem = { - __init__(vitem: VItem, eitem: EItem, i: int, src: bool): any; - refresh(): any; +export class TItem extends Ray { + __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): any => { throw new NotImplementedError(); } + refresh = (): any => { throw new NotImplementedError(); } } -export type GraphScene = { - __init__(): any; - set_graph(g: Graph): any; - add_items(): any; - mousePressEvent(e: QGraphicsSceneMouseEvent): any; - mouseMoveEvent(e: QGraphicsSceneMouseEvent): any; - mouseReleaseEvent(_: QGraphicsSceneMouseEvent): any; +export class GraphScene extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } + set_graph = (g = Graph): any => { throw new NotImplementedError(); } + add_items = (): any => { throw new NotImplementedError(); } + mousePressEvent = (e = QGraphicsSceneMouseEvent): any => { throw new NotImplementedError(); } + mouseMoveEvent = (e = QGraphicsSceneMouseEvent): any => { throw new NotImplementedError(); } + mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): any => { throw new NotImplementedError(); } } -export type GraphView = { - __init__(): any; - set_graph(g: Graph): any; +export class GraphView extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } + set_graph = (g = Graph): any => { throw new NotImplementedError(); } } -export type ChypHighlighter = { - __init__(doc: QTextDocument): any; - set_current_region(region: Optional>, status: int): any; - highlightBlock(text: str): any; +export class ChypHighlighter extends Ray { + __init__ = (doc = QTextDocument): any => { throw new NotImplementedError(); } + set_current_region = (region = Optional(Tuple(int,int)), status = int): any => { throw new NotImplementedError(); } + highlightBlock = (text = str): any => { throw new NotImplementedError(); } } -export type MainWindow = { - __init__(): any; - remove_empty_editor(): any; - update_file_name(): any; - tab_changed(i: int): any; - update_themes(): any; - recent_files(): any; - update_recent_files(): any; - add_tab(ed: Editor, title: str): any; - close_tab(): any; - new(): any; - open(): any; - save(): any; - save_as(): any; - undo(): any; - redo(): any; - show_errors(): any; - add_rewrite_step(): any; - repeat_rewrite_step(): any; - next_rewrite(): any; - next_part(): any; - previous_part(): any; - next_tab(): any; - previous_tab(): any; - goto_import(): any; - closeEvent(e: QCloseEvent): any; - build_menu(): any; +export class MainWindow extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } + remove_empty_editor = (): any => { throw new NotImplementedError(); } + update_file_name = (): any => { throw new NotImplementedError(); } + tab_changed = (i = int): any => { throw new NotImplementedError(); } + update_themes = (): any => { throw new NotImplementedError(); } + recent_files = (): any => { throw new NotImplementedError(); } + update_recent_files = (): any => { throw new NotImplementedError(); } + add_tab = (ed = Editor, title = str): any => { throw new NotImplementedError(); } + close_tab = (): any => { throw new NotImplementedError(); } + new = (): any => { throw new NotImplementedError(); } + open = (): any => { throw new NotImplementedError(); } + save = (): any => { throw new NotImplementedError(); } + save_as = (): any => { throw new NotImplementedError(); } + undo = (): any => { throw new NotImplementedError(); } + redo = (): any => { throw new NotImplementedError(); } + show_errors = (): any => { throw new NotImplementedError(); } + add_rewrite_step = (): any => { throw new NotImplementedError(); } + repeat_rewrite_step = (): any => { throw new NotImplementedError(); } + next_rewrite = (): any => { throw new NotImplementedError(); } + next_part = (): any => { throw new NotImplementedError(); } + previous_part = (): any => { throw new NotImplementedError(); } + next_tab = (): any => { throw new NotImplementedError(); } + previous_tab = (): any => { throw new NotImplementedError(); } + goto_import = (): any => { throw new NotImplementedError(); } + closeEvent = (e = QCloseEvent): any => { throw new NotImplementedError(); } + build_menu = (): any => { throw new NotImplementedError(); } } -export type Match = { - __init__(): any; - __str__(): any; - copy(): any; - try_add_vertex(domain_vertex: int, codomain_vertex: int): any; - try_add_edge(domain_edge: int, codomain_edge: int): any; - domain_neighbourhood_mapped(vertex: int): any; - map_scalars(): any; - more(): any; - is_total(): any; - is_surjective(): any; - is_injective(): any; - is_convex(): any; +export class Match extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } + __str__ = (): any => { throw new NotImplementedError(); } + copy = (): any => { throw new NotImplementedError(); } + try_add_vertex = (domain_vertex = int, codomain_vertex = int): any => { throw new NotImplementedError(); } + try_add_edge = (domain_edge = int, codomain_edge = int): any => { throw new NotImplementedError(); } + domain_neighbourhood_mapped = (vertex = int): any => { throw new NotImplementedError(); } + map_scalars = (): any => { throw new NotImplementedError(); } + more = (): any => { throw new NotImplementedError(); } + is_total = (): any => { throw new NotImplementedError(); } + is_surjective = (): any => { throw new NotImplementedError(); } + is_injective = (): any => { throw new NotImplementedError(); } + is_convex = (): any => { throw new NotImplementedError(); } } -export type Matches = { - __init__(domain: Graph, codomain: Graph): any; - __iter__(): any; - __next__(): any; +export class Matches extends Ray { + __init__ = (domain = Graph, codomain = Graph): any => { throw new NotImplementedError(); } + __iter__ = (): any => { throw new NotImplementedError(); } + __next__ = (): any => { throw new NotImplementedError(); } } -export type RuleError = { +export class RuleError extends Ray { } -export type Rule = { - __init__(lhs: Graph, rhs: Graph): any; - copy(): any; - converse(): any; - is_left_linear(): any; +export class Rule extends Ray { + get lhs(): Ray { throw new NotImplementedError(); } + get rhs(): Ray { throw new NotImplementedError(); } + + /** + * TODO: Put the name on each side of the rule, not the '-' hacky thing + */ + get name(): Ray { throw new NotImplementedError(); } + get equiv(): Ray { throw new NotImplementedError(); } + + __init__ = (lhs = Graph, rhs = Graph, name = str(''), equiv = bool(True)): any => { throw new NotImplementedError(); } + copy = (): any => { throw new NotImplementedError(); } + converse = (): any => { throw new NotImplementedError(); } + is_left_linear = (): any => { throw new NotImplementedError(); } } -export type RewriteState = { - __init__(sequence: int, state: State): any; - check(): any; +export class RewriteState extends Ray { + __init__ = (sequence = int, state = State): any => { throw new NotImplementedError(); } + check = (): any => { throw new NotImplementedError(); } } -export type State = { - __init__(): any; - part_with_index_at(pos: int): any; - part_at(pos: int): any; - var(items: List): any; - module_name(items: List): any; - num(items: List): any; - type_element(items: list): any; - type_term(items: list | None>): any; - id(items: list): any; - id0(_: List): any; - eq(_: List): any; - le(_: List): any; - perm_indices(items: list): any; - size_list(items: list): any; - par(items: List): any; - gen_color(items: List): any; - color(items: List): any; - import_let(items: List): any; - tactic(items: List): any; - nested_term(items: List): any; +export class State extends Ray { + __init__ = (): any => { throw new NotImplementedError(); } + part_with_index_at = (pos = int): any => { throw new NotImplementedError(); } + part_at = (pos = int): any => { throw new NotImplementedError(); } + var = (items = List(Any)): any => { throw new NotImplementedError(); } + module_name = (items = List(Any)): any => { throw new NotImplementedError(); } + num = (items = List(Any)): any => { throw new NotImplementedError(); } + type_element = (items = list(Any)): any => { throw new NotImplementedError(); } + type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): any => { throw new NotImplementedError(); } + id = (items = list(Any)): any => { throw new NotImplementedError(); } + id0 = (_ = List(Any)): any => { throw new NotImplementedError(); } + eq = (_ = List(Any)): any => { throw new NotImplementedError(); } + le = (_ = List(Any)): any => { throw new NotImplementedError(); } + perm_indices = (items = list(int)): any => { throw new NotImplementedError(); } + size_list = (items = list(int)): any => { throw new NotImplementedError(); } + par = (items = List(Any)): any => { throw new NotImplementedError(); } + gen_color = (items = List(Any)): any => { throw new NotImplementedError(); } + color = (items = List(Any)): any => { throw new NotImplementedError(); } + import_let = (items = List(Any)): any => { throw new NotImplementedError(); } + tactic = (items = List(Any)): any => { throw new NotImplementedError(); } + nested_term = (items = List(Any)): any => { throw new NotImplementedError(); } } -export type Tactic = { - __init__(local_state: RewriteState, args: List): any; - repeat(rw: Callable, rules: List): any; - error(message: str): any; - has_goal(): any; - global_rules(): any; - lookup_rule(rule_expr: str): any; - add_refl_to_context(graph: Graph, ident: str): any; - add_rule_to_context(rule_name: str): any; - __lhs(target: str): any; - __rhs(target: str): any; - __set_lhs(target: str, graph: Graph): any; - __set_rhs(target: str, graph: Graph): any; - rewrite_lhs(rule_expr: str): any; - rewrite_rhs(rule_expr: str): any; - rewrite_lhs1(rule_expr: str): any; - rewrite_rhs1(rule_expr: str): any; - validate_goal(): any; - lhs(): any; - rhs(): any; - lhs_size(): any; - rhs_size(): any; - highlight_lhs(vertices: Set, edges: Set): any; - highlight_rhs(vertices: Set, edges: Set): any; - __reset(): any; - next_rhs(current: str): any; - run_check(): any; - name(): any; - check(): any; - make_rhs(): any; +export class Tactic extends Ray { + __init__ = (local_state = RewriteState, args = List(str)): any => { throw new NotImplementedError(); } + repeat = (rw = Callable([str], bool), rules = List(str)): any => { throw new NotImplementedError(); } + error = (message = str): any => { throw new NotImplementedError(); } + has_goal = (): any => { throw new NotImplementedError(); } + global_rules = (): any => { throw new NotImplementedError(); } + lookup_rule = (rule_expr = str): any => { throw new NotImplementedError(); } + add_refl_to_context = (graph = Graph, ident = str): any => { throw new NotImplementedError(); } + add_rule_to_context = (rule_name = str): any => { throw new NotImplementedError(); } + __lhs = (target = str): any => { throw new NotImplementedError(); } + __rhs = (target = str): any => { throw new NotImplementedError(); } + __set_lhs = (target = str, graph = Graph): any => { throw new NotImplementedError(); } + __set_rhs = (target = str, graph = Graph): any => { throw new NotImplementedError(); } + rewrite_lhs = (rule_expr = str): any => { throw new NotImplementedError(); } + rewrite_rhs = (rule_expr = str): any => { throw new NotImplementedError(); } + rewrite_lhs1 = (rule_expr = str): any => { throw new NotImplementedError(); } + rewrite_rhs1 = (rule_expr = str): any => { throw new NotImplementedError(); } + validate_goal = (): any => { throw new NotImplementedError(); } + lhs = (): any => { throw new NotImplementedError(); } + rhs = (): any => { throw new NotImplementedError(); } + lhs_size = (): any => { throw new NotImplementedError(); } + rhs_size = (): any => { throw new NotImplementedError(); } + highlight_lhs = (vertices = Set(int), edges = Set(int)): any => { throw new NotImplementedError(); } + highlight_rhs = (vertices = Set(int), edges = Set(int)): any => { throw new NotImplementedError(); } + __reset = (): any => { throw new NotImplementedError(); } + next_rhs = (current = str): any => { throw new NotImplementedError(); } + run_check = (): any => { throw new NotImplementedError(); } + name = (): any => { throw new NotImplementedError(); } + check = (): any => { throw new NotImplementedError(); } + make_rhs = (): any => { throw new NotImplementedError(); } } -export type RuleTac = { - name(): any; - make_rhs(): any; - check(): any; +export class RuleTac extends Ray { + name = (): any => { throw new NotImplementedError(); } + make_rhs = (): any => { throw new NotImplementedError(); } + check = (): any => { throw new NotImplementedError(); } } -export type SimpTac = { - name(): any; - __prepare_rules(): any; - make_rhs(): any; - check(): any; +export class SimpTac extends Ray { + name = (): any => { throw new NotImplementedError(); } + __prepare_rules = (): any => { throw new NotImplementedError(); } + make_rhs = (): any => { throw new NotImplementedError(); } + check = (): any => { throw new NotImplementedError(); } } diff --git a/src/@orbitmines/external/implementations/chyp/Chyp2.ts b/src/@orbitmines/external/implementations/chyp/Chyp2.ts new file mode 100644 index 0000000..eebaf1b --- /dev/null +++ b/src/@orbitmines/external/implementations/chyp/Chyp2.ts @@ -0,0 +1,317 @@ + + +export type int = any; +export type list = any; +export type Iterable = any; +export type set = any; +export type str = any; +export type QKeyEvent = any; +export type Optional = any; +export type Tuple = any; +export type QObject = any; +export type Union = any; +export type QModelIndex = any; +export type QPersistentModelIndex = any; +export type QWidget = any; +export type List = any; +export type Qt = any; +export type Orientation = any; +export type QPainter = any; +export type QStyleOptionGraphicsItem = any; +export type bool = any; +export type QGraphicsSceneMouseEvent = any; +export type QTextDocument = any; +export type editor = any; +export type QCloseEvent = any; +export type Any = any; +export type tuple = any; +export type None = any; +export type state = any; +export type Callable = any; +export type Set = any; + +export type GraphError = { +} + +export type VData = { + __init__(): any; +} + +export type EData = { + __init__(): any; + __repr__(): any; + box_size(): any; +} + +export type Graph = { + __init__(): any; + copy(): any; + vertices(): any; + edges(): any; + num_vertices(): any; + num_edges(): any; + domain(): any; + codomain(): any; + vertex_data(v: int): any; + edge_data(e: int): any; + edge_domain(edge_id: int): any; + edge_codomain(edge_id: int): any; + in_edges(v: int): any; + out_edges(v: int): any; + source(e: int): any; + target(e: int): any; + add_vertex(): any; + add_edge(s: list, t: list): any; + remove_vertex(v: int): any; + remove_edge(e: int): any; + add_inputs(inp: list): any; + add_outputs(outp: list): any; + set_inputs(inp: list): any; + set_outputs(outp: list): any; + inputs(): any; + outputs(): any; + is_input(v: int): any; + is_output(v: int): any; + is_boundary(v: int): any; + successors(vs: Iterable): any; + merge_vertices(v: int, w: int): any; + explode_vertex(v: int): any; + insert_id_after(v: int): any; + tensor(other: Graph): any; + __mul__(other: Graph): any; + compose(other: Graph): any; + __rshift__(other: Graph): any; + highlight(vertices: set, edges: set): any; + unhighlight(): any; +} + +export type Chyp = { + __init__(): any; +} + +export type CodeView = { + __init__(): any; + popup_visible(): any; + set_completions(completions: Iterable): any; + ident_at_cursor(): any; + insert_completion(completion: str): any; + keyPressEvent(e: QKeyEvent): any; + set_current_region(region: Optional>): any; + add_line_below(text: str): any; +} + +export type CodeCompletionModel = { + __init__(parent: QObject): any; + set_completions(completions: Iterable): any; + data(index: Union): any; + rowCount(): any; +} + +export type ChypDocument = { + __init__(parent: QWidget): any; + confirm_close(): any; + add_to_recent_files(file_name: str): any; + open(file_name: str): any; + save(): any; + save_as(): any; +} + +export type Editor = { + __init__(): any; + title(): any; + reset_state(): any; + invalidate_text(): any; + next_part(): any; + jump_to_error(): any; + show_errors(): any; + show_at_cursor(): any; + next_rewrite_at_cursor(): any; + repeat_step_at_cursor(): any; + update_state(): any; + import_at_cursor(): any; +} + +export type CheckThread = { + __init__(rw: RewriteState): any; + run(): any; +} + +export type ErrorListModel = { + __init__(): any; + set_errors(errors: List>): any; + data(index: Union): any; + headerData(section: int, orientation: Orientation): any; + index(row: int, column: int): any; + columnCount(): any; + rowCount(): any; + parent(): any; +} + +export type EItem = { + __init__(g: Graph, e: int): any; + paint(painter: QPainter, option: QStyleOptionGraphicsItem): any; +} + +export type VItem = { + __init__(g: Graph, v: int): any; + refresh(): any; +} + +export type TItem = { + __init__(vitem: VItem, eitem: EItem, i: int, src: bool): any; + refresh(): any; +} + +export type GraphScene = { + __init__(): any; + set_graph(g: Graph): any; + add_items(): any; + mousePressEvent(e: QGraphicsSceneMouseEvent): any; + mouseMoveEvent(e: QGraphicsSceneMouseEvent): any; + mouseReleaseEvent(_: QGraphicsSceneMouseEvent): any; +} + +export type GraphView = { + __init__(): any; + set_graph(g: Graph): any; +} + +export type ChypHighlighter = { + __init__(doc: QTextDocument): any; + set_current_region(region: Optional>, status: int): any; + highlightBlock(text: str): any; +} + +export type MainWindow = { + __init__(): any; + remove_empty_editor(): any; + update_file_name(): any; + tab_changed(i: int): any; + update_themes(): any; + recent_files(): any; + update_recent_files(): any; + add_tab(ed: Editor, title: str): any; + close_tab(): any; + new(): any; + open(): any; + save(): any; + save_as(): any; + undo(): any; + redo(): any; + show_errors(): any; + add_rewrite_step(): any; + repeat_rewrite_step(): any; + next_rewrite(): any; + next_part(): any; + previous_part(): any; + next_tab(): any; + previous_tab(): any; + goto_import(): any; + closeEvent(e: QCloseEvent): any; + build_menu(): any; +} + +export type Match = { + __init__(): any; + __str__(): any; + copy(): any; + try_add_vertex(domain_vertex: int, codomain_vertex: int): any; + try_add_edge(domain_edge: int, codomain_edge: int): any; + domain_neighbourhood_mapped(vertex: int): any; + map_scalars(): any; + more(): any; + is_total(): any; + is_surjective(): any; + is_injective(): any; + is_convex(): any; +} + +export type Matches = { + __init__(domain: Graph, codomain: Graph): any; + __iter__(): any; + __next__(): any; +} + +export type RuleError = { +} + +export type Rule = { + __init__(lhs: Graph, rhs: Graph): any; + copy(): any; + converse(): any; + is_left_linear(): any; +} + +export type RewriteState = { + __init__(sequence: int, state: State): any; + check(): any; +} + +export type State = { + __init__(): any; + part_with_index_at(pos: int): any; + part_at(pos: int): any; + var(items: List): any; + module_name(items: List): any; + num(items: List): any; + type_element(items: list): any; + type_term(items: list | None>): any; + id(items: list): any; + id0(_: List): any; + eq(_: List): any; + le(_: List): any; + perm_indices(items: list): any; + size_list(items: list): any; + par(items: List): any; + gen_color(items: List): any; + color(items: List): any; + import_let(items: List): any; + tactic(items: List): any; + nested_term(items: List): any; +} + +export type Tactic = { + __init__(local_state: RewriteState, args: List): any; + repeat(rw: Callable, rules: List): any; + error(message: str): any; + has_goal(): any; + global_rules(): any; + lookup_rule(rule_expr: str): any; + add_refl_to_context(graph: Graph, ident: str): any; + add_rule_to_context(rule_name: str): any; + __lhs(target: str): any; + __rhs(target: str): any; + __set_lhs(target: str, graph: Graph): any; + __set_rhs(target: str, graph: Graph): any; + rewrite_lhs(rule_expr: str): any; + rewrite_rhs(rule_expr: str): any; + rewrite_lhs1(rule_expr: str): any; + rewrite_rhs1(rule_expr: str): any; + validate_goal(): any; + lhs(): any; + rhs(): any; + lhs_size(): any; + rhs_size(): any; + highlight_lhs(vertices: Set, edges: Set): any; + highlight_rhs(vertices: Set, edges: Set): any; + __reset(): any; + next_rhs(current: str): any; + run_check(): any; + name(): any; + check(): any; + make_rhs(): any; +} + +export type RuleTac = { + name(): any; + make_rhs(): any; + check(): any; +} + +export type SimpTac = { + name(): any; + __prepare_rules(): any; + make_rhs(): any; + check(): any; +} + diff --git a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx index c1b0d5d..12d47b4 100644 --- a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx @@ -1,11 +1,14 @@ import React from "react"; import IEventListener, {mergeListeners} from "../../../js/react/IEventListener"; import {VisualizationCanvas} from "../../../explorer/Visualization"; -import {AutoRenderedRay, SimpleRenderedRay} from "../../../explorer/OrbitMinesExplorer"; +import {AutoRenderedRay, BinarySuperposition, Loop, SimpleRenderedRay} from "../../../explorer/OrbitMinesExplorer"; import {RayType} from "../../../explorer/Ray"; import {Center} from "@react-three/drei"; - +/** + * TODO: Import .chyp files + * TODO: Export to .chyp files + */ const ChypCanvas = ( { listeners = [], @@ -31,25 +34,48 @@ const ChypCanvas = ( {...mergeListeners(...listeners, listener)} >
- - - - - - - - - - - + {/* Iterator */} + {/**/} + {/* */} + {/* */} + {/**/} + + {/* Grid/Dictionary/... */} + {/**/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/**/} + + {/* Loop memory */} + {/**/} + {/* */} + {/* */} + {/**/} + + + {/* Being able to reference any part from within the structure - self-compiling */} + {/**/} + {/* */} + {/* */} + {/* /!**!/*/} + {/**/} + + + + + + + + {/**/} +
- {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - } @@ -62,11 +88,9 @@ export const ChypExplorer = ( } ) => { - const listener: IEventListener = { - - } + const listener: IEventListener = {} - return + return } export default ChypCanvas; \ No newline at end of file diff --git a/useless_junk/generate_chyp.js b/useless_junk/generate_chyp.js index 905ff80..bdebe1d 100644 --- a/useless_junk/generate_chyp.js +++ b/useless_junk/generate_chyp.js @@ -92,7 +92,7 @@ function generateTypeScriptTypes(classesAndMethods) { const typeScriptCode = []; classesAndMethods.forEach((classInfo) => { - typeScriptCode.push(`export type ${classInfo.name} = {`); + typeScriptCode.push(`export class ${classInfo.name} extends Ray {`); classInfo.methods.forEach((method) => { const params = method.arguments.map((arg) => `${arg.name}: ${ @@ -102,7 +102,7 @@ function generateTypeScriptTypes(classesAndMethods) { .replaceAll(/<(.*)>,/g, "$1[],") .split('.')) }`).join(', '); - typeScriptCode.push(` ${method.name}(${params}): ${method.returnType};`); + typeScriptCode.push(` ${method.name} = (${params}): ${method.returnType} => { throw new NotImplementedError(); }`); }); typeScriptCode.push('}\n'); @@ -127,4 +127,4 @@ ${generateTypeScriptTypes(classesAndMethods)} `; -fs.writeFileSync('../src/@orbitmines/external/implementations/chyp/ChypCanvas.ts', typeScriptCode) \ No newline at end of file +fs.writeFileSync('../src/@orbitmines/external/implementations/chyp/Chyp.ts', typeScriptCode) \ No newline at end of file From ab75a2ee080b2b1600220af8010a34f18b6f737f Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Fri, 5 Jan 2024 22:45:45 +0100 Subject: [PATCH 006/138] 2024/02/05 - Some simple translations --- src/@orbitmines/explorer/Ray.ts | 24 +- .../external/implementations/chyp/Chyp.ts | 551 +++++++++++------- 2 files changed, 365 insertions(+), 210 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 55feceb..681a213 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -51,7 +51,9 @@ export enum RayType { VERTEX = '--|--', } -export type Arbitrary = () => Option; +// TODO: Option = Ray + +export type Arbitrary = (...args: any[]) => Option | T; /** * https://en.wikipedia.org/wiki/Homoiconicity @@ -70,6 +72,12 @@ export interface PossiblyHomoiconic> { * TODO: * - Homotopy equivalence merely as some direction/reversibility constraint on some direction, ignoring additional structure (or incorporating it into the equiv) at the vertices. (Could be loosened where certain vertex-equivalences are also part of the homotopy) * - Induced ignorance/equivalence along arbitrary rays. + * - Usual way of thinking about vertices is what the coninuations are here - phrase that somewhjere + * + * TODO: Any javascript class, allow warpper of function names around any ray, as a possible match + * TODO: All the methods defined here should be implemented in some Ray structure at some point + * TODO: Easy method to create initial/terminal, right now it's a bit obscure + * */ export class Ray implements @@ -77,6 +85,7 @@ export class Ray AsyncIterable, Iterable + // TODO: Array, Dictionary... { js: () => Option; @@ -88,6 +97,8 @@ export class Ray self = (): Option => this.vertex(); + [index: number]: Ray; + constructor({ initial, vertex, @@ -192,6 +203,8 @@ export class Ray // TODO NEEDS TO CHECK IF THERE'S SOME INITIAL DEFIEND ; for defining if it has halted + equivalent = (other: Ray) => { throw new NotImplementedError(); } + get type(): RayType { if (this.is_reference()) return RayType.REFERENCE; @@ -205,6 +218,15 @@ export class Ray count = (): Ray => { throw new NotImplementedError() } copy = (): Ray => { throw new NotImplementedError() } + at = (steps: Ray | Arbitrary): Ray => { throw new NotImplementedError(); } + + /** + * Cast to some JavaScript object + */ + cast = (): T => { throw new NotImplementedError(); }; + + // TODO: Should give the program that does the mapping, not the result + map = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } *traverse(): Generator {} diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index 7ea27e2..50fc6b4 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -1,9 +1,19 @@ -import {JS, Ray} from "../../../explorer/Ray"; +import {Arbitrary, JS, Ray} from "../../../explorer/Ray"; import { NotImplementedError } from "../../../explorer/errors/errors"; import {Option} from "../../../js/utils/Option"; /** - * Probably want all these types at runtime, to display them + * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. + * GitHub: https://github.com/akissinger/chyp + * + * NOTE: + * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. + * + * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? + * + * TODO: Probably want all these types at runtime, to display them + * + * TODO: Graph boundary is automatic with this structure? */ export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; @@ -90,18 +100,80 @@ export class VData extends Ray { get y(): Ray { throw new NotImplementedError(); } // TODO: Just some boolean - get hightlight(): Ray { throw new NotImplementedError(); } + get highlight(): Ray { throw new NotImplementedError(); } + + get value(): Ray { throw new NotImplementedError(); } + + /** + * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. + * + * TODO ; // set[int] = set() + */ + get in_edges(): Ray { throw new NotImplementedError(); } + get out_edges(): Ray { throw new NotImplementedError(); } + + /** + * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. + */ + get in_indices(): Ray { throw new NotImplementedError(); } + get out_indices(): Ray { throw new NotImplementedError(); } + + /** + * Initialize a VData instance. + */ + __init__ = (): Ray => { throw new NotImplementedError(); } + - __init__ = (): any => { throw new NotImplementedError(); } + is_input = (): Ray => this.in_indices.count() > 0; + is_output = (): Ray => this.out_indices.count() > 0; + is_boundary = (): Ray => this.is_input() || this.is_output(); + // TODO: Probably generalizable + + /** + * Initial + * @param other + */ + merge = (other: VData): Ray => { + // TODO: other is destroyed + // TODO: Vertices + // this.initial().force().equivalent(other.initial().force()); + // this.terminal().force().equivalent(other.initial().force()); + + throw new NotImplementedError(); + } } export class EData extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } - __repr__ = (): any => { throw new NotImplementedError(); } - box_size = (): any => { throw new NotImplementedError(); } - toString = (): string => this.__repr__(); + get s(): Ray { throw new NotImplementedError(); } + get t(): Ray { throw new NotImplementedError(); } + get x(): Ray { throw new NotImplementedError(); } + get y(): Ray { throw new NotImplementedError(); } + get fg(): Ray { throw new NotImplementedError(); } + get bg(): Ray { throw new NotImplementedError(); } + get highlight(): Ray { throw new NotImplementedError(); } + get hyper(): Ray { throw new NotImplementedError(); } + get value(): Ray { throw new NotImplementedError(); } + + __init__ = (): Ray => { throw new NotImplementedError(); } + __repr__ = (): Ray => { throw new NotImplementedError(); } + box_size = (): Ray => { throw new NotImplementedError(); } + + toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL + + get source() { return this.s }; + get target() { return this.t }; + + // TODO: Shouldn't be here, this should either be implemented on Ray if it's general enough, of just remain here as an artifact + protected ___domain = (ray: Ray) => ray.map(_ => { + const vertex: VData = _.cast(); + return [vertex.vtype, vertex.size]; + }); + + domain = (): Ray => this.___domain(this.source); + codomain = (): Ray => this.___domain(this.target); + } /** @@ -128,199 +200,260 @@ export class Graph extends Ray { get vindex(): Ray { throw new NotImplementedError(); } get eindex(): Ray { throw new NotImplementedError(); } - __init__ = (): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } // Implemented on Ray - // copy = (): any => { throw new NotImplementedError(); } - - vertices = (): any => { throw new NotImplementedError(); } - edges = (): any => { throw new NotImplementedError(); } - num_vertices = (): any => { throw new NotImplementedError(); } - num_edges = (): any => { throw new NotImplementedError(); } - domain = (): any => { throw new NotImplementedError(); } - codomain = (): any => { throw new NotImplementedError(); } - vertex_data = (v = int): any => { throw new NotImplementedError(); } - edge_data = (e = int): any => { throw new NotImplementedError(); } - edge_domain = (edge_id = int): any => { throw new NotImplementedError(); } - edge_codomain = (edge_id = int): any => { throw new NotImplementedError(); } - in_edges = (v = int): any => { throw new NotImplementedError(); } - out_edges = (v = int): any => { throw new NotImplementedError(); } - source = (e = int): any => { throw new NotImplementedError(); } - target = (e = int): any => { throw new NotImplementedError(); } - add_vertex = (): any => { throw new NotImplementedError(); } - add_edge = (s = list(int), t = list(int)): any => { throw new NotImplementedError(); } - remove_vertex = (v = int): any => { throw new NotImplementedError(); } - remove_edge = (e = int): any => { throw new NotImplementedError(); } - add_inputs = (inp = list(int)): any => { throw new NotImplementedError(); } - add_outputs = (outp = list(int)): any => { throw new NotImplementedError(); } - set_inputs = (inp = list(int)): any => { throw new NotImplementedError(); } - set_outputs = (outp = list(int)): any => { throw new NotImplementedError(); } + // copy = (): Ray => { throw new NotImplementedError(); } + + // TODO .keys + vertices = (): Ray => this.vdata; + edges = (): Ray => this.edata; + + // TODO: Shouldn't be here, this should either be implemented on Ray if it's general enough, of just remain here as an artifact + protected ___domain = (ray: Ray) => ray.map(_ => { + const vertex: VData = _.cast(); + return [vertex.vtype, vertex.size]; + }); + + /** + * Return the domain of the graph. + * + * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. + */ + domain = (): Ray => this.___domain(this.inputs()); + + /** + * Return the domain of the graph. + * + * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. + */ + codomain = (): Ray => this.___domain(this.outputs()); + + /** + * Return the :class:`VData` associated with vertex id `v`. + * + * @param v Integer identifier of the vertex. + */ + vertex_data = (v = int): VData => this.vertices().at(v).cast(); + + /** + * Return the :class:`EData` associated with edge id `e`. + * + * @param e Integer identifier of the edge. + */ + edge_data = (e = int): EData => this.edges().at(e).cast(); + + add_vertex = (): Ray => { throw new NotImplementedError(); } + add_edge = (s = list(int), t = list(int)): Ray => { throw new NotImplementedError(); } + remove_vertex = (v = int): Ray => { throw new NotImplementedError(); } + remove_edge = (e = int): Ray => { throw new NotImplementedError(); } + add_inputs = (inp = list(int)): Ray => { throw new NotImplementedError(); } + add_outputs = (outp = list(int)): Ray => { throw new NotImplementedError(); } + set_inputs = (inp = list(int)): Ray => { throw new NotImplementedError(); } + set_outputs = (outp = list(int)): Ray => { throw new NotImplementedError(); } // Return the list of vertex ids of the graph inputs. - inputs = (): any => { throw new NotImplementedError(); } + inputs = (): Ray => { throw new NotImplementedError(); } // Return the list of vertex ids of the graph outputs. - outputs = (): any => { throw new NotImplementedError(); } + outputs = (): Ray => { throw new NotImplementedError(); } + + // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. _inputs = this.inputs; _outputs = this.outputs; - is_input = (v = int): any => { throw new NotImplementedError(); } - is_output = (v = int): any => { throw new NotImplementedError(); } - is_boundary = (v = int): any => { throw new NotImplementedError(); } - successors = (vs = Iterable(int)): any => { throw new NotImplementedError(); } - merge_vertices = (v = int, w = int): any => { throw new NotImplementedError(); } - explode_vertex = (v = int): any => { throw new NotImplementedError(); } - insert_id_after = (v = int): any => { throw new NotImplementedError(); } - tensor = (other = Graph): any => { throw new NotImplementedError(); } - __mul__ = (other = Graph): any => { throw new NotImplementedError(); } - compose = (other = Graph): any => { throw new NotImplementedError(); } - __rshift__ = (other = Graph): any => { throw new NotImplementedError(); } - highlight = (vertices = set(int), edges = set(int)): any => { throw new NotImplementedError(); } - unhighlight = (): any => { throw new NotImplementedError(); } + + // TODO: Move these to a "reference-like" structure, need to be on VData.. + + /** + * All these are just delegations from some Vertex/Edge structure. + */ + // .vertices + num_vertices = (): Ray => this.vertices().count(); + + // .edges + num_edges = (): Ray => this.edges().count(); + + // .vertex_data + is_input = (v = int): Ray => this.vertex_data(v).is_input(); + is_output = (v = int): Ray => this.vertex_data(v).is_output(); + is_boundary = (v = int): Ray => this.vertex_data(v).is_boundary(); + in_edges = (v = int): Ray => this.vertex_data(v).in_edges; + out_edges = (v = int): Ray => this.vertex_data(v).out_edges; + + // .edge_data + source = (e = int): Ray => this.edge_data(e).source; + target = (e = int): Ray => this.edge_data(e).target; + edge_domain = (edge_id = int): Ray => this.edge_data(edge_id).domain(); + edge_codomain = (edge_id = int): Ray => this.edge_data(edge_id).codomain(); + + + successors = (vs = Iterable(int)): Ray => { throw new NotImplementedError(); } + + /** + * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. + * + * @param v Integer identifier of the vertex into which to merge `w`. + * @param w Integer identifier of the vertex to merge into `v`. + */ + merge_vertices = (v = int, w = int): Ray => this.vertex_data(v).merge(this.vertex_data(w)); + + explode_vertex = (v = int): Ray => { throw new NotImplementedError(); } + insert_id_after = (v = int): Ray => { throw new NotImplementedError(); } + tensor = (other = Graph): Ray => { throw new NotImplementedError(); } + __mul__ = (other = Graph): Ray => { throw new NotImplementedError(); } + compose = (other = Graph): Ray => { throw new NotImplementedError(); } + __rshift__ = (other = Graph): Ray => { throw new NotImplementedError(); } + highlight = (vertices = set(int), edges = set(int)): Ray => { throw new NotImplementedError(); } + unhighlight = (): Ray => { throw new NotImplementedError(); } } export class Chyp extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } } export class CodeView extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } - popup_visible = (): any => { throw new NotImplementedError(); } - set_completions = (completions = Iterable(str)): any => { throw new NotImplementedError(); } - ident_at_cursor = (): any => { throw new NotImplementedError(); } - insert_completion = (completion = str): any => { throw new NotImplementedError(); } - keyPressEvent = (e = QKeyEvent): any => { throw new NotImplementedError(); } - set_current_region = (region = Optional(Tuple(int,int))): any => { throw new NotImplementedError(); } - add_line_below = (text = str): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } + popup_visible = (): Ray => { throw new NotImplementedError(); } + set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } + ident_at_cursor = (): Ray => { throw new NotImplementedError(); } + insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } + keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } + set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } + add_line_below = (text = str): Ray => { throw new NotImplementedError(); } } export class CodeCompletionModel extends Ray { - __init__ = (parent = QObject): any => { throw new NotImplementedError(); } - set_completions = (completions = Iterable(str)): any => { throw new NotImplementedError(); } - data = (index = Union(QModelIndex, QPersistentModelIndex)): any => { throw new NotImplementedError(); } - rowCount = (): any => { throw new NotImplementedError(); } + __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } + set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } + data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } + rowCount = (): Ray => { throw new NotImplementedError(); } } export class ChypDocument extends Ray { - __init__ = (parent = QWidget): any => { throw new NotImplementedError(); } - confirm_close = (): any => { throw new NotImplementedError(); } - add_to_recent_files = (file_name = str): any => { throw new NotImplementedError(); } - open = (file_name = str): any => { throw new NotImplementedError(); } - save = (): any => { throw new NotImplementedError(); } - save_as = (): any => { throw new NotImplementedError(); } + __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } + confirm_close = (): Ray => { throw new NotImplementedError(); } + add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } + open = (file_name = str): Ray => { throw new NotImplementedError(); } + save = (): Ray => { throw new NotImplementedError(); } + save_as = (): Ray => { throw new NotImplementedError(); } } export class Editor extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } - title = (): any => { throw new NotImplementedError(); } - reset_state = (): any => { throw new NotImplementedError(); } - invalidate_text = (): any => { throw new NotImplementedError(); } - next_part = (): any => { throw new NotImplementedError(); } - jump_to_error = (): any => { throw new NotImplementedError(); } - show_errors = (): any => { throw new NotImplementedError(); } - show_at_cursor = (): any => { throw new NotImplementedError(); } - next_rewrite_at_cursor = (): any => { throw new NotImplementedError(); } - repeat_step_at_cursor = (): any => { throw new NotImplementedError(); } - update_state = (): any => { throw new NotImplementedError(); } - import_at_cursor = (): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } + title = (): Ray => { throw new NotImplementedError(); } + reset_state = (): Ray => { throw new NotImplementedError(); } + invalidate_text = (): Ray => { throw new NotImplementedError(); } + next_part = (): Ray => { throw new NotImplementedError(); } + jump_to_error = (): Ray => { throw new NotImplementedError(); } + show_errors = (): Ray => { throw new NotImplementedError(); } + show_at_cursor = (): Ray => { throw new NotImplementedError(); } + next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } + repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } + update_state = (): Ray => { throw new NotImplementedError(); } + import_at_cursor = (): Ray => { throw new NotImplementedError(); } } export class CheckThread extends Ray { - __init__ = (rw = RewriteState): any => { throw new NotImplementedError(); } - run = (): any => { throw new NotImplementedError(); } + __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } + run = (): Ray => { throw new NotImplementedError(); } } export class ErrorListModel extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } - set_errors = (errors = List(Tuple(str, int, str))): any => { throw new NotImplementedError(); } - data = (index = Union(QModelIndex, QPersistentModelIndex)): any => { throw new NotImplementedError(); } - headerData = (section = int, orientation = Orientation): any => { throw new NotImplementedError(); } - index = (row = int, column = int): any => { throw new NotImplementedError(); } - columnCount = (): any => { throw new NotImplementedError(); } - rowCount = (): any => { throw new NotImplementedError(); } - parent = (): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } + set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } + data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } + headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } + index = (row = int, column = int): Ray => { throw new NotImplementedError(); } + columnCount = (): Ray => { throw new NotImplementedError(); } + rowCount = (): Ray => { throw new NotImplementedError(); } + parent = (): Ray => { throw new NotImplementedError(); } } export class EItem extends Ray { - __init__ = (g = Graph, e = int): any => { throw new NotImplementedError(); } - paint = (painter = QPainter, option = QStyleOptionGraphicsItem): any => { throw new NotImplementedError(); } + __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } + paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } } export class VItem extends Ray { - __init__ = (g = Graph, v = int): any => { throw new NotImplementedError(); } - refresh = (): any => { throw new NotImplementedError(); } + __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } + refresh = (): Ray => { throw new NotImplementedError(); } } export class TItem extends Ray { - __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): any => { throw new NotImplementedError(); } - refresh = (): any => { throw new NotImplementedError(); } + __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } + refresh = (): Ray => { throw new NotImplementedError(); } } export class GraphScene extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } - set_graph = (g = Graph): any => { throw new NotImplementedError(); } - add_items = (): any => { throw new NotImplementedError(); } - mousePressEvent = (e = QGraphicsSceneMouseEvent): any => { throw new NotImplementedError(); } - mouseMoveEvent = (e = QGraphicsSceneMouseEvent): any => { throw new NotImplementedError(); } - mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } + set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } + add_items = (): Ray => { throw new NotImplementedError(); } + mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } + mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } + mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } } export class GraphView extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } - set_graph = (g = Graph): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } + set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } } export class ChypHighlighter extends Ray { - __init__ = (doc = QTextDocument): any => { throw new NotImplementedError(); } - set_current_region = (region = Optional(Tuple(int,int)), status = int): any => { throw new NotImplementedError(); } - highlightBlock = (text = str): any => { throw new NotImplementedError(); } + __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } + set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } + highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } } export class MainWindow extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } - remove_empty_editor = (): any => { throw new NotImplementedError(); } - update_file_name = (): any => { throw new NotImplementedError(); } - tab_changed = (i = int): any => { throw new NotImplementedError(); } - update_themes = (): any => { throw new NotImplementedError(); } - recent_files = (): any => { throw new NotImplementedError(); } - update_recent_files = (): any => { throw new NotImplementedError(); } - add_tab = (ed = Editor, title = str): any => { throw new NotImplementedError(); } - close_tab = (): any => { throw new NotImplementedError(); } - new = (): any => { throw new NotImplementedError(); } - open = (): any => { throw new NotImplementedError(); } - save = (): any => { throw new NotImplementedError(); } - save_as = (): any => { throw new NotImplementedError(); } - undo = (): any => { throw new NotImplementedError(); } - redo = (): any => { throw new NotImplementedError(); } - show_errors = (): any => { throw new NotImplementedError(); } - add_rewrite_step = (): any => { throw new NotImplementedError(); } - repeat_rewrite_step = (): any => { throw new NotImplementedError(); } - next_rewrite = (): any => { throw new NotImplementedError(); } - next_part = (): any => { throw new NotImplementedError(); } - previous_part = (): any => { throw new NotImplementedError(); } - next_tab = (): any => { throw new NotImplementedError(); } - previous_tab = (): any => { throw new NotImplementedError(); } - goto_import = (): any => { throw new NotImplementedError(); } - closeEvent = (e = QCloseEvent): any => { throw new NotImplementedError(); } - build_menu = (): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } + remove_empty_editor = (): Ray => { throw new NotImplementedError(); } + update_file_name = (): Ray => { throw new NotImplementedError(); } + tab_changed = (i = int): Ray => { throw new NotImplementedError(); } + update_themes = (): Ray => { throw new NotImplementedError(); } + recent_files = (): Ray => { throw new NotImplementedError(); } + update_recent_files = (): Ray => { throw new NotImplementedError(); } + add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } + close_tab = (): Ray => { throw new NotImplementedError(); } + new = (): Ray => { throw new NotImplementedError(); } + open = (): Ray => { throw new NotImplementedError(); } + save = (): Ray => { throw new NotImplementedError(); } + save_as = (): Ray => { throw new NotImplementedError(); } + undo = (): Ray => { throw new NotImplementedError(); } + redo = (): Ray => { throw new NotImplementedError(); } + show_errors = (): Ray => { throw new NotImplementedError(); } + add_rewrite_step = (): Ray => { throw new NotImplementedError(); } + repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } + next_rewrite = (): Ray => { throw new NotImplementedError(); } + next_part = (): Ray => { throw new NotImplementedError(); } + previous_part = (): Ray => { throw new NotImplementedError(); } + next_tab = (): Ray => { throw new NotImplementedError(); } + previous_tab = (): Ray => { throw new NotImplementedError(); } + goto_import = (): Ray => { throw new NotImplementedError(); } + closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } + build_menu = (): Ray => { throw new NotImplementedError(); } } export class Match extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } - __str__ = (): any => { throw new NotImplementedError(); } - copy = (): any => { throw new NotImplementedError(); } - try_add_vertex = (domain_vertex = int, codomain_vertex = int): any => { throw new NotImplementedError(); } - try_add_edge = (domain_edge = int, codomain_edge = int): any => { throw new NotImplementedError(); } - domain_neighbourhood_mapped = (vertex = int): any => { throw new NotImplementedError(); } - map_scalars = (): any => { throw new NotImplementedError(); } - more = (): any => { throw new NotImplementedError(); } - is_total = (): any => { throw new NotImplementedError(); } - is_surjective = (): any => { throw new NotImplementedError(); } - is_injective = (): any => { throw new NotImplementedError(); } - is_convex = (): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } + __str__ = (): Ray => { throw new NotImplementedError(); } + + // Implemented on Ray + // TODO; doesnt copy the graphs at domain/codomain + // copy = (): Ray => { throw new NotImplementedError(); } + + try_add_vertex = (domain_vertex = int, codomain_vertex = int): Ray => { throw new NotImplementedError(); } + try_add_edge = (domain_edge = int, codomain_edge = int): Ray => { throw new NotImplementedError(); } + domain_neighbourhood_mapped = (vertex = int): Ray => { throw new NotImplementedError(); } + map_scalars = (): Ray => { throw new NotImplementedError(); } + more = (): Ray => { throw new NotImplementedError(); } + is_total = (): Ray => { throw new NotImplementedError(); } + is_surjective = (): Ray => { throw new NotImplementedError(); } + is_injective = (): Ray => { throw new NotImplementedError(); } + is_convex = (): Ray => { throw new NotImplementedError(); } } export class Matches extends Ray { - __init__ = (domain = Graph, codomain = Graph): any => { throw new NotImplementedError(); } - __iter__ = (): any => { throw new NotImplementedError(); } - __next__ = (): any => { throw new NotImplementedError(); } + __init__ = (domain = Graph, codomain = Graph): Ray => { throw new NotImplementedError(); } + __iter__ = (): Ray => { throw new NotImplementedError(); } + __next__ = (): Ray => { throw new NotImplementedError(); } } export class RuleError extends Ray { @@ -336,82 +469,82 @@ export class Rule extends Ray { get name(): Ray { throw new NotImplementedError(); } get equiv(): Ray { throw new NotImplementedError(); } - __init__ = (lhs = Graph, rhs = Graph, name = str(''), equiv = bool(True)): any => { throw new NotImplementedError(); } - copy = (): any => { throw new NotImplementedError(); } - converse = (): any => { throw new NotImplementedError(); } - is_left_linear = (): any => { throw new NotImplementedError(); } + __init__ = (lhs = Graph, rhs = Graph, name = str(''), equiv = bool(True)): Ray => { throw new NotImplementedError(); } + copy = (): Ray => { throw new NotImplementedError(); } + converse = (): Ray => { throw new NotImplementedError(); } + is_left_linear = (): Ray => { throw new NotImplementedError(); } } export class RewriteState extends Ray { - __init__ = (sequence = int, state = State): any => { throw new NotImplementedError(); } - check = (): any => { throw new NotImplementedError(); } + __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } } export class State extends Ray { - __init__ = (): any => { throw new NotImplementedError(); } - part_with_index_at = (pos = int): any => { throw new NotImplementedError(); } - part_at = (pos = int): any => { throw new NotImplementedError(); } - var = (items = List(Any)): any => { throw new NotImplementedError(); } - module_name = (items = List(Any)): any => { throw new NotImplementedError(); } - num = (items = List(Any)): any => { throw new NotImplementedError(); } - type_element = (items = list(Any)): any => { throw new NotImplementedError(); } - type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): any => { throw new NotImplementedError(); } - id = (items = list(Any)): any => { throw new NotImplementedError(); } - id0 = (_ = List(Any)): any => { throw new NotImplementedError(); } - eq = (_ = List(Any)): any => { throw new NotImplementedError(); } - le = (_ = List(Any)): any => { throw new NotImplementedError(); } - perm_indices = (items = list(int)): any => { throw new NotImplementedError(); } - size_list = (items = list(int)): any => { throw new NotImplementedError(); } - par = (items = List(Any)): any => { throw new NotImplementedError(); } - gen_color = (items = List(Any)): any => { throw new NotImplementedError(); } - color = (items = List(Any)): any => { throw new NotImplementedError(); } - import_let = (items = List(Any)): any => { throw new NotImplementedError(); } - tactic = (items = List(Any)): any => { throw new NotImplementedError(); } - nested_term = (items = List(Any)): any => { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } + part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } + part_at = (pos = int): Ray => { throw new NotImplementedError(); } + var = (items = List(Any)): Ray => { throw new NotImplementedError(); } + module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } + num = (items = List(Any)): Ray => { throw new NotImplementedError(); } + type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } + type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } + id = (items = list(Any)): Ray => { throw new NotImplementedError(); } + id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } + eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } + le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } + perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } + size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } + par = (items = List(Any)): Ray => { throw new NotImplementedError(); } + gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } + color = (items = List(Any)): Ray => { throw new NotImplementedError(); } + import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } + tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } + nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } } export class Tactic extends Ray { - __init__ = (local_state = RewriteState, args = List(str)): any => { throw new NotImplementedError(); } - repeat = (rw = Callable([str], bool), rules = List(str)): any => { throw new NotImplementedError(); } - error = (message = str): any => { throw new NotImplementedError(); } - has_goal = (): any => { throw new NotImplementedError(); } - global_rules = (): any => { throw new NotImplementedError(); } - lookup_rule = (rule_expr = str): any => { throw new NotImplementedError(); } - add_refl_to_context = (graph = Graph, ident = str): any => { throw new NotImplementedError(); } - add_rule_to_context = (rule_name = str): any => { throw new NotImplementedError(); } - __lhs = (target = str): any => { throw new NotImplementedError(); } - __rhs = (target = str): any => { throw new NotImplementedError(); } - __set_lhs = (target = str, graph = Graph): any => { throw new NotImplementedError(); } - __set_rhs = (target = str, graph = Graph): any => { throw new NotImplementedError(); } - rewrite_lhs = (rule_expr = str): any => { throw new NotImplementedError(); } - rewrite_rhs = (rule_expr = str): any => { throw new NotImplementedError(); } - rewrite_lhs1 = (rule_expr = str): any => { throw new NotImplementedError(); } - rewrite_rhs1 = (rule_expr = str): any => { throw new NotImplementedError(); } - validate_goal = (): any => { throw new NotImplementedError(); } - lhs = (): any => { throw new NotImplementedError(); } - rhs = (): any => { throw new NotImplementedError(); } - lhs_size = (): any => { throw new NotImplementedError(); } - rhs_size = (): any => { throw new NotImplementedError(); } - highlight_lhs = (vertices = Set(int), edges = Set(int)): any => { throw new NotImplementedError(); } - highlight_rhs = (vertices = Set(int), edges = Set(int)): any => { throw new NotImplementedError(); } - __reset = (): any => { throw new NotImplementedError(); } - next_rhs = (current = str): any => { throw new NotImplementedError(); } - run_check = (): any => { throw new NotImplementedError(); } - name = (): any => { throw new NotImplementedError(); } - check = (): any => { throw new NotImplementedError(); } - make_rhs = (): any => { throw new NotImplementedError(); } + __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } + repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } + error = (message = str): Ray => { throw new NotImplementedError(); } + has_goal = (): Ray => { throw new NotImplementedError(); } + global_rules = (): Ray => { throw new NotImplementedError(); } + lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } + add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } + add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } + __lhs = (target = str): Ray => { throw new NotImplementedError(); } + __rhs = (target = str): Ray => { throw new NotImplementedError(); } + __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } + __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } + rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } + rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } + rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } + rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } + validate_goal = (): Ray => { throw new NotImplementedError(); } + lhs = (): Ray => { throw new NotImplementedError(); } + rhs = (): Ray => { throw new NotImplementedError(); } + lhs_size = (): Ray => { throw new NotImplementedError(); } + rhs_size = (): Ray => { throw new NotImplementedError(); } + highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } + highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } + __reset = (): Ray => { throw new NotImplementedError(); } + next_rhs = (current = str): Ray => { throw new NotImplementedError(); } + run_check = (): Ray => { throw new NotImplementedError(); } + name = (): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } + make_rhs = (): Ray => { throw new NotImplementedError(); } } export class RuleTac extends Ray { - name = (): any => { throw new NotImplementedError(); } - make_rhs = (): any => { throw new NotImplementedError(); } - check = (): any => { throw new NotImplementedError(); } + name = (): Ray => { throw new NotImplementedError(); } + make_rhs = (): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } } export class SimpTac extends Ray { - name = (): any => { throw new NotImplementedError(); } - __prepare_rules = (): any => { throw new NotImplementedError(); } - make_rhs = (): any => { throw new NotImplementedError(); } - check = (): any => { throw new NotImplementedError(); } + name = (): Ray => { throw new NotImplementedError(); } + __prepare_rules = (): Ray => { throw new NotImplementedError(); } + make_rhs = (): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } } From 922614c8a691aa392da223ced5b07fadc96d8479 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 6 Jan 2024 11:06:54 +0100 Subject: [PATCH 007/138] 2024/02/06 - Some simple translations --- src/@orbitmines/explorer/Ray.ts | 3 + .../external/implementations/chyp/Chyp.ts | 115 ++++++- .../external/implementations/chyp/Chyp2.ts | 317 ------------------ 3 files changed, 106 insertions(+), 329 deletions(-) delete mode 100644 src/@orbitmines/external/implementations/chyp/Chyp2.ts diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 681a213..d2b3e31 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -78,6 +78,9 @@ export interface PossiblyHomoiconic> { * TODO: All the methods defined here should be implemented in some Ray structure at some point * TODO: Easy method to create initial/terminal, right now it's a bit obscure * + * TODO: Maybe want a way to destroy from one end, so that if other references try to look, they won't find additional structure. - More as a javascript implementation quirck if anything? + * + * TODO: Can do some workaround overloading through properties, at least for +/- */ export class Ray implements diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index 50fc6b4..6533ec1 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -6,6 +6,8 @@ import {Option} from "../../../js/utils/Option"; * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. * GitHub: https://github.com/akissinger/chyp * + * A simple way of phrasing this conversion, is that the concept of a 'Vertex', 'Edge', 'Graph', 'Rule', ..., 'Rewrite' are merged into one thing: a Ray. + * * NOTE: * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. * @@ -14,6 +16,13 @@ import {Option} from "../../../js/utils/Option"; * TODO: Probably want all these types at runtime, to display them * * TODO: Graph boundary is automatic with this structure? + * + * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? + * + * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. + * + * TODO: Can just move the terminal which holds the oointer to the boundary + * */ export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; @@ -108,6 +117,7 @@ export class VData extends Ray { * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. * * TODO ; // set[int] = set() + * TODO ; these are just the initial/terminal sides of a Ray. they're just duplicated */ get in_edges(): Ray { throw new NotImplementedError(); } get out_edges(): Ray { throw new NotImplementedError(); } @@ -146,8 +156,13 @@ export class VData extends Ray { export class EData extends Ray { + // TODO: this is just the initial frame get s(): Ray { throw new NotImplementedError(); } + + // TODO: this is just the terminal frame get t(): Ray { throw new NotImplementedError(); } + + get x(): Ray { throw new NotImplementedError(); } get y(): Ray { throw new NotImplementedError(); } get fg(): Ray { throw new NotImplementedError(); } @@ -243,25 +258,101 @@ export class Graph extends Ray { */ edge_data = (e = int): EData => this.edges().at(e).cast(); - add_vertex = (): Ray => { throw new NotImplementedError(); } - add_edge = (s = list(int), t = list(int)): Ray => { throw new NotImplementedError(); } + // TODO: Shouldnt be here + ___next_index = (name = int(-1), index: Ray): Ray => { + // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) + const current = name === -1 ? index : Math.max(name, index); + return current + 1; + } + + /** + * Add a new vertex to the graph. + * + * @param name The value carried by this vertex (currently unused). + * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. + * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). + */ + add_vertex = (name = int(-1), vertex: VData): VData => { + this.vindex = this.___next_index(name, this.vindex); + + this.vdata[this.vindex - 1] = vertex; + return vertex; + } + + /** + * Add a new hyperedge to the graph. + * + * @param s + * @param t + */ + add_edge = (name = int(-1), edge: EData): EData => { + this.eindex = this.___next_index(name, this.eindex); + + this.edata[this.eindex - 1] = edge; + + // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) + // for v in s: + // self.vdata[v].out_edges.add(e) + // for v in t: + // self.vdata[v].in_edges.add(e) + + return edge; + } + // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. + remove_vertex = (v = int): Ray => { throw new NotImplementedError(); } - remove_edge = (e = int): Ray => { throw new NotImplementedError(); } - add_inputs = (inp = list(int)): Ray => { throw new NotImplementedError(); } - add_outputs = (outp = list(int)): Ray => { throw new NotImplementedError(); } - set_inputs = (inp = list(int)): Ray => { throw new NotImplementedError(); } - set_outputs = (outp = list(int)): Ray => { throw new NotImplementedError(); } + + /** + * Remove an edge from the graph. + * + * @param e Integer identifier of the edge to remove. + */ + remove_edge = (e = int): Ray => { + // TODO: destroy any reference of it (could just do this lazy) + // in/out edges from all vertices + delete this.edata[e]; + } + + // TODO: Can these be overlaoded in properties using -=, += in TS? + + /** + * Append `inp` to the inputs of the graph. + * + * @param inp The list of vertex integer identifiers of the appended inputs. + */ + add_inputs = (inp = list(int)): Ray => { + this.inputs().continues_with(inp); // TODO: Perhaps splat + } + /** + * Append `outp` to the outputs of the graph. + * + * @param outp The list of vertex integer identifiers of the appended outputs. + */ + add_outputs = (outp = list(int)): Ray => { + this.outputs().continues_with(outp); // TODO: Perhaps splat + } + // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) + + + // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. + // Return the list of vertex ids of the graph inputs. - inputs = (): Ray => { throw new NotImplementedError(); } + get inputs(): Ray { throw new NotImplementedError(); } // Return the list of vertex ids of the graph outputs. - outputs = (): Ray => { throw new NotImplementedError(); } + get outputs(): Ray { throw new NotImplementedError(); } - // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. - _inputs = this.inputs; - _outputs = this.outputs; + // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs + set inputs(ray = list(int)) { throw new NotImplementedError(); } + set outputs(ray = list(int)) { throw new NotImplementedError(); } // TODO: Move these to a "reference-like" structure, need to be on VData.. + /** + * These are all just slightly differently abstracted in TypeScript here to make them a little more native. + */ + set_inputs = (inp = list(int)): Ray => this.inputs = inp; + set_outputs = (outp = list(int)): Ray => this.outputs = outp; + /** * All these are just delegations from some Vertex/Edge structure. */ diff --git a/src/@orbitmines/external/implementations/chyp/Chyp2.ts b/src/@orbitmines/external/implementations/chyp/Chyp2.ts deleted file mode 100644 index eebaf1b..0000000 --- a/src/@orbitmines/external/implementations/chyp/Chyp2.ts +++ /dev/null @@ -1,317 +0,0 @@ - - -export type int = any; -export type list = any; -export type Iterable = any; -export type set = any; -export type str = any; -export type QKeyEvent = any; -export type Optional = any; -export type Tuple = any; -export type QObject = any; -export type Union = any; -export type QModelIndex = any; -export type QPersistentModelIndex = any; -export type QWidget = any; -export type List = any; -export type Qt = any; -export type Orientation = any; -export type QPainter = any; -export type QStyleOptionGraphicsItem = any; -export type bool = any; -export type QGraphicsSceneMouseEvent = any; -export type QTextDocument = any; -export type editor = any; -export type QCloseEvent = any; -export type Any = any; -export type tuple = any; -export type None = any; -export type state = any; -export type Callable = any; -export type Set = any; - -export type GraphError = { -} - -export type VData = { - __init__(): any; -} - -export type EData = { - __init__(): any; - __repr__(): any; - box_size(): any; -} - -export type Graph = { - __init__(): any; - copy(): any; - vertices(): any; - edges(): any; - num_vertices(): any; - num_edges(): any; - domain(): any; - codomain(): any; - vertex_data(v: int): any; - edge_data(e: int): any; - edge_domain(edge_id: int): any; - edge_codomain(edge_id: int): any; - in_edges(v: int): any; - out_edges(v: int): any; - source(e: int): any; - target(e: int): any; - add_vertex(): any; - add_edge(s: list, t: list): any; - remove_vertex(v: int): any; - remove_edge(e: int): any; - add_inputs(inp: list): any; - add_outputs(outp: list): any; - set_inputs(inp: list): any; - set_outputs(outp: list): any; - inputs(): any; - outputs(): any; - is_input(v: int): any; - is_output(v: int): any; - is_boundary(v: int): any; - successors(vs: Iterable): any; - merge_vertices(v: int, w: int): any; - explode_vertex(v: int): any; - insert_id_after(v: int): any; - tensor(other: Graph): any; - __mul__(other: Graph): any; - compose(other: Graph): any; - __rshift__(other: Graph): any; - highlight(vertices: set, edges: set): any; - unhighlight(): any; -} - -export type Chyp = { - __init__(): any; -} - -export type CodeView = { - __init__(): any; - popup_visible(): any; - set_completions(completions: Iterable): any; - ident_at_cursor(): any; - insert_completion(completion: str): any; - keyPressEvent(e: QKeyEvent): any; - set_current_region(region: Optional>): any; - add_line_below(text: str): any; -} - -export type CodeCompletionModel = { - __init__(parent: QObject): any; - set_completions(completions: Iterable): any; - data(index: Union): any; - rowCount(): any; -} - -export type ChypDocument = { - __init__(parent: QWidget): any; - confirm_close(): any; - add_to_recent_files(file_name: str): any; - open(file_name: str): any; - save(): any; - save_as(): any; -} - -export type Editor = { - __init__(): any; - title(): any; - reset_state(): any; - invalidate_text(): any; - next_part(): any; - jump_to_error(): any; - show_errors(): any; - show_at_cursor(): any; - next_rewrite_at_cursor(): any; - repeat_step_at_cursor(): any; - update_state(): any; - import_at_cursor(): any; -} - -export type CheckThread = { - __init__(rw: RewriteState): any; - run(): any; -} - -export type ErrorListModel = { - __init__(): any; - set_errors(errors: List>): any; - data(index: Union): any; - headerData(section: int, orientation: Orientation): any; - index(row: int, column: int): any; - columnCount(): any; - rowCount(): any; - parent(): any; -} - -export type EItem = { - __init__(g: Graph, e: int): any; - paint(painter: QPainter, option: QStyleOptionGraphicsItem): any; -} - -export type VItem = { - __init__(g: Graph, v: int): any; - refresh(): any; -} - -export type TItem = { - __init__(vitem: VItem, eitem: EItem, i: int, src: bool): any; - refresh(): any; -} - -export type GraphScene = { - __init__(): any; - set_graph(g: Graph): any; - add_items(): any; - mousePressEvent(e: QGraphicsSceneMouseEvent): any; - mouseMoveEvent(e: QGraphicsSceneMouseEvent): any; - mouseReleaseEvent(_: QGraphicsSceneMouseEvent): any; -} - -export type GraphView = { - __init__(): any; - set_graph(g: Graph): any; -} - -export type ChypHighlighter = { - __init__(doc: QTextDocument): any; - set_current_region(region: Optional>, status: int): any; - highlightBlock(text: str): any; -} - -export type MainWindow = { - __init__(): any; - remove_empty_editor(): any; - update_file_name(): any; - tab_changed(i: int): any; - update_themes(): any; - recent_files(): any; - update_recent_files(): any; - add_tab(ed: Editor, title: str): any; - close_tab(): any; - new(): any; - open(): any; - save(): any; - save_as(): any; - undo(): any; - redo(): any; - show_errors(): any; - add_rewrite_step(): any; - repeat_rewrite_step(): any; - next_rewrite(): any; - next_part(): any; - previous_part(): any; - next_tab(): any; - previous_tab(): any; - goto_import(): any; - closeEvent(e: QCloseEvent): any; - build_menu(): any; -} - -export type Match = { - __init__(): any; - __str__(): any; - copy(): any; - try_add_vertex(domain_vertex: int, codomain_vertex: int): any; - try_add_edge(domain_edge: int, codomain_edge: int): any; - domain_neighbourhood_mapped(vertex: int): any; - map_scalars(): any; - more(): any; - is_total(): any; - is_surjective(): any; - is_injective(): any; - is_convex(): any; -} - -export type Matches = { - __init__(domain: Graph, codomain: Graph): any; - __iter__(): any; - __next__(): any; -} - -export type RuleError = { -} - -export type Rule = { - __init__(lhs: Graph, rhs: Graph): any; - copy(): any; - converse(): any; - is_left_linear(): any; -} - -export type RewriteState = { - __init__(sequence: int, state: State): any; - check(): any; -} - -export type State = { - __init__(): any; - part_with_index_at(pos: int): any; - part_at(pos: int): any; - var(items: List): any; - module_name(items: List): any; - num(items: List): any; - type_element(items: list): any; - type_term(items: list | None>): any; - id(items: list): any; - id0(_: List): any; - eq(_: List): any; - le(_: List): any; - perm_indices(items: list): any; - size_list(items: list): any; - par(items: List): any; - gen_color(items: List): any; - color(items: List): any; - import_let(items: List): any; - tactic(items: List): any; - nested_term(items: List): any; -} - -export type Tactic = { - __init__(local_state: RewriteState, args: List): any; - repeat(rw: Callable, rules: List): any; - error(message: str): any; - has_goal(): any; - global_rules(): any; - lookup_rule(rule_expr: str): any; - add_refl_to_context(graph: Graph, ident: str): any; - add_rule_to_context(rule_name: str): any; - __lhs(target: str): any; - __rhs(target: str): any; - __set_lhs(target: str, graph: Graph): any; - __set_rhs(target: str, graph: Graph): any; - rewrite_lhs(rule_expr: str): any; - rewrite_rhs(rule_expr: str): any; - rewrite_lhs1(rule_expr: str): any; - rewrite_rhs1(rule_expr: str): any; - validate_goal(): any; - lhs(): any; - rhs(): any; - lhs_size(): any; - rhs_size(): any; - highlight_lhs(vertices: Set, edges: Set): any; - highlight_rhs(vertices: Set, edges: Set): any; - __reset(): any; - next_rhs(current: str): any; - run_check(): any; - name(): any; - check(): any; - make_rhs(): any; -} - -export type RuleTac = { - name(): any; - make_rhs(): any; - check(): any; -} - -export type SimpTac = { - name(): any; - __prepare_rules(): any; - make_rhs(): any; - check(): any; -} - From abfe21433c4735b459177eaf5a13b2bc5f9023d3 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 6 Jan 2024 11:42:56 +0100 Subject: [PATCH 008/138] 2024/02/06 - Some simple translations --- src/@orbitmines/explorer/Ray.ts | 4 +- .../external/implementations/chyp/Chyp.ts | 131 +++++++++++++++++- 2 files changed, 132 insertions(+), 3 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index d2b3e31..580ccc2 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -228,8 +228,10 @@ export class Ray */ cast = (): T => { throw new NotImplementedError(); }; - // TODO: Should give the program that does the mapping, not the result + // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' map = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } + all = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } + filter = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } *traverse(): Generator {} diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index 6533ec1..3a187d4 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -23,6 +23,8 @@ import {Option} from "../../../js/utils/Option"; * * TODO: Can just move the terminal which holds the oointer to the boundary * + * TODO: Automatically generate visual examples of all the methods + * */ export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; @@ -212,6 +214,7 @@ export class Graph extends Ray { // Mapping from integer identifiers of each hyperedge to its data. get edata(): Ray { throw new NotImplementedError(); } + // TODO: Can probably generate these on the fly, or cache them automatically get vindex(): Ray { throw new NotImplementedError(); } get eindex(): Ray { throw new NotImplementedError(); } @@ -392,12 +395,136 @@ export class Graph extends Ray { __mul__ = (other = Graph): Ray => { throw new NotImplementedError(); } compose = (other = Graph): Ray => { throw new NotImplementedError(); } __rshift__ = (other = Graph): Ray => { throw new NotImplementedError(); } - highlight = (vertices = set(int), edges = set(int)): Ray => { throw new NotImplementedError(); } - unhighlight = (): Ray => { throw new NotImplementedError(); } + + /** + * Set the `highlight` flag for a set of vertices and edges. + * + * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. + * + * @param vertices A set of vertices to highlight. + * @param edges A set of edges to highlight. + */ + highlight = (vertices = set(int), edges = set(int)): Ray => { + // TODO Again, these could be merged + this.vdata + .filter(vertex => vertices.includes(vertex)) + .all(vertex => vertex.cast().highlight = bool(true)); + this.edata + .filter(edge => edges.includes(edge)) + .all(edge => edge.cast().highlight = bool(true)); + } + + /** + * Clear the `highlight` flag for all vertices/edges. + * + * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. + */ + unhighlight = (): Ray => { + // TODO: These could be merged + this.vdata + .all(vertex => vertex.cast().highlight = bool(false)); + this.edata + .all(edge => edge.cast().highlight = bool(false)); + } } export class Chyp extends Ray { __init__ = (): Ray => { throw new NotImplementedError(); } + + /** + * Load a .chyp graph file from the given path. + */ + load_graph = (path = str) => { + // TODO: From localStorage for now? + // with open(path) as f: + // g = graph_from_json(f.read()) + } + + /** + * Return a graph corresponding to the identity map. + * + * This graph has a single vertex which is both an input and an output. + */ + identity = (vertex: VData): Graph => { + const graph = new Graph(); + + vertex.x = 0; // TODO automatic>? + vertex.y = 0; + graph.add_vertex(int(-1), vertex); + // TODO synce input/output automatically? + // g.set_inputs([v]) + // g.set_outputs([v]) + + return graph; + } + + + ___map_domain = (domain: Ray, _default: VData): Ray => { + return domain.map(([vtype, size], i) => { + const vertex: VData = _default.copy().cast(); + // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere + vertex.x = -1.5; + vertex.y = i - (i-1) / 2; + + return vertex; + }) + } + + /** + * Return a graph with one hyperedge and given domain and codomain. + * + * @param _default + * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. + * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. + */ + gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { + const graph = new Graph(); + + const inputs = this.___map_domain(domain, _default) + .map(vertex => graph.add_vertex(vertex)); + const outputs = this.___map_domain(codomain, _default) + .map(vertex => graph.add_vertex(vertex)); + + // TODO This is probably automatic at some point, remove + const edge = new EData(); + edge.s = inputs; + edge.t = outputs; + graph.add_edge(int(-1), edge); + // g.set_inputs(inputs) + // g.set_outputs(outputs) + + return graph; + } + + graph_from_json = (json_string = str): Graph => { + const json = JSON.parse(json_string().as_string()); // TODO + + const graph = new Graph(); + + // TODO: Don't do this so naively + // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), + // y=float(vd["y"] if "y" in vd else 0.0), + // value=vd["value"] if "value" in vd else "", + // name=int(v)) + // for e, ed in j["edges"].items(): + // g.add_edge(s=[int(v) for v in ed["s"]], + // t=[int(v) for v in ed["t"]], + // value=ed["value"] if "value" in ed else "", + // x=float(ed["x"]) if "x" in ed else 0.0, + // y=float(ed["y"]) if "y" in ed else 0.0, + // hyper=bool(ed["hyper"]) if "hyper" in ed else True, + // name=int(e)) + // + // g.set_inputs([int(v) for v in j["inputs"]]) + // g.set_outputs([int(v) for v in j["outputs"]]) + // json.vertices.forEach(((vertex, i) => graph.add_vertex( + // i, + // new VData() + // )); + + return graph; + } + } export class CodeView extends Ray { From d3e7a577b15b26219960990a09c592a935c1df28 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 6 Jan 2024 12:14:31 +0100 Subject: [PATCH 009/138] 2024/02/06 - Some simple translations --- src/@orbitmines/explorer/Ray.ts | 2 + .../external/implementations/chyp/Chyp.ts | 87 ++++++++++++++++--- 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 580ccc2..3e33113 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -220,6 +220,8 @@ export class Ray } count = (): Ray => { throw new NotImplementedError() } + + // TODO; Could return the ignorant reference to both instances, or just the result., .. copy = (): Ray => { throw new NotImplementedError() } at = (steps: Ray | Arbitrary): Ray => { throw new NotImplementedError(); } diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index 3a187d4..3f8c083 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -1,4 +1,4 @@ -import {Arbitrary, JS, Ray} from "../../../explorer/Ray"; +import {Arbitrary, empty, JS, Ray} from "../../../explorer/Ray"; import { NotImplementedError } from "../../../explorer/errors/errors"; import {Option} from "../../../js/utils/Option"; @@ -11,7 +11,7 @@ import {Option} from "../../../js/utils/Option"; * NOTE: * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. * - * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? + * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. * * TODO: Probably want all these types at runtime, to display them * @@ -59,6 +59,8 @@ export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImple export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export class ValueError extends Error {} + /** * Non-default vertex types are identified by a string label * @@ -133,7 +135,13 @@ export class VData extends Ray { /** * Initialize a VData instance. */ - __init__ = (): Ray => { throw new NotImplementedError(); } + __init__ = (): Ray => { + this.highlight = bool(False); + this.in_edges = set(int); + this.out_edges = set(int); + this.in_indices = set(int); + this.out_indices = set(int); + } is_input = (): Ray => this.in_indices.count() > 0; @@ -143,7 +151,7 @@ export class VData extends Ray { // TODO: Probably generalizable /** - * Initial + * * @param other */ merge = (other: VData): Ray => { @@ -156,6 +164,9 @@ export class VData extends Ray { } } +/** + * Data associated with a single edge. + */ export class EData extends Ray { // TODO: this is just the initial frame @@ -173,9 +184,25 @@ export class EData extends Ray { get hyper(): Ray { throw new NotImplementedError(); } get value(): Ray { throw new NotImplementedError(); } - __init__ = (): Ray => { throw new NotImplementedError(); } - __repr__ = (): Ray => { throw new NotImplementedError(); } - box_size = (): Ray => { throw new NotImplementedError(); } + __init__ = (): Ray => { + this.s = empty(); + this.t = empty(); + this.highlight = bool(False); + } + + __repr__ = (): Ray => { throw new NotImplementedError(); + // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' + } + + // TODO: More stuff to relate it to the screen that shouldnt be here. + /** + * Return how many width 'units' this box needs to display nicely. + * + * This uses a simple rule: + * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. + * - Otherwise draw as a larger (size 2) box. + */ + box_size = (): Ray => (this.s.count() <= 1 && this.t.count() <= 1) ? 1 : 2; toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL @@ -218,7 +245,10 @@ export class Graph extends Ray { get vindex(): Ray { throw new NotImplementedError(); } get eindex(): Ray { throw new NotImplementedError(); } - __init__ = (): Ray => { throw new NotImplementedError(); } + __init__ = (): Ray => { + this.vindex = 0; + this.edindex = 0; + } // Implemented on Ray // copy = (): Ray => { throw new NotImplementedError(); } @@ -303,7 +333,36 @@ export class Graph extends Ray { } // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. - remove_vertex = (v = int): Ray => { throw new NotImplementedError(); } + /** + * Remove a vertex from the graph. + * + * This removes a single vertex. + * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. + * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. + * + * @param v + * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. + */ + remove_vertex = (v = int, strict: boolean = false): Ray => { + // TODO: destroy any reference of it (could just do this lazy) + // TODO: as delegation + + if (strict) { + if (this.vertex_data(v).in_edges.count() > 0 || this.vertex_data(v).out_edges > 0) { + throw new ValueError('Attempting to remove vertex with adjacent' + + 'edges while strict == True.'); + } + + if (this.inputs().includes(v) || this.outputs.includes(v)) { + throw new ValueError('Attempting to remove boundary vertex while' + + 'strict == True.'); + + }// TODO CAN BE SIMPLIFIED + } + + // in/out edges from all vertices + delete this.vdata[v]; + } /** * Remove an edge from the graph. @@ -378,8 +437,16 @@ export class Graph extends Ray { edge_domain = (edge_id = int): Ray => this.edge_data(edge_id).domain(); edge_codomain = (edge_id = int): Ray => this.edge_data(edge_id).codomain(); + /** + * Return vertices that lie on a directed path from any of `vs`. + * @param vs + */ + successors = (vs = Iterable(int)): Ray => { + // TODO: Just traverse the rays, deduplicate using the index, where vs is one or more (so again which part of the ray is selected). + - successors = (vs = Iterable(int)): Ray => { throw new NotImplementedError(); } + throw new NotImplementedError(); + } /** * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. From 91c186a50de8b3067acf2a40e2beef8ab8e41cfa Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 6 Jan 2024 12:25:43 +0100 Subject: [PATCH 010/138] 2024/02/06 - Some simple translations --- .../external/implementations/chyp/Chyp.ts | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index 3f8c083..ee56205 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -25,6 +25,8 @@ import {Option} from "../../../js/utils/Option"; * * TODO: Automatically generate visual examples of all the methods * + * TODO: Runtime errors as rays + * */ export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; @@ -73,7 +75,7 @@ export const VType = JS.Iterable([str, None]); * * TODO probably hooked as a boolean, one successful the other not */ -export class GraphError extends Ray { +export class GraphError extends Error { } /** @@ -563,6 +565,42 @@ export class Chyp extends Ray { return graph; } + /** + * Return a graph corresponding to the given permutation. + * + * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. + * + * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. + * + * @param p A permutation given as an n-element list of integers from 0 to n-1. + * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. + */ + perm = (p = list(int), domain: Ray, _default: VData) => { + + const graph = new Graph(); + const num_wires = p.count(); + + if (num_wires !== domain.count()) + throw new GraphError(`Domain ${domain} does not match length of permutation.`) + + // TODO use ___map_domain + const inputs = domain.map(([vtype, size], i) => { + const vertex: VData = _default.copy().cast(); + // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere + vertex.x = 0; + vertex.y = i - (num_wires - 1) / 2; + + return vertex; + }) + .map(vertex => graph.add_vertex(vertex)); + // const outputs = num_wires.range(i => [inputs[p[i]]) + + // TODO Should be automatic + // g.set_inputs(inputs) + // g.set_outputs(outputs) + return graph; + } + graph_from_json = (json_string = str): Graph => { const json = JSON.parse(json_string().as_string()); // TODO From f9b5f2d164973e60f806c278aa553f6bab85ad19 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 6 Jan 2024 13:51:56 +0100 Subject: [PATCH 011/138] 2024/02/06 - Some simple translations --- src/@orbitmines/explorer/Ray.ts | 2 + .../external/implementations/chyp/Chyp.ts | 57 +++++++++++++++---- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 3e33113..4ddea68 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -81,6 +81,8 @@ export interface PossiblyHomoiconic> { * TODO: Maybe want a way to destroy from one end, so that if other references try to look, they won't find additional structure. - More as a javascript implementation quirck if anything? * * TODO: Can do some workaround overloading through properties, at least for +/- + * + * TODO: Singlke keybind for now to show/hide the ray disambiguation or 'dead edges/..'/ */ export class Ray implements diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index ee56205..9fb5a5d 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -75,8 +75,8 @@ export const VType = JS.Iterable([str, None]); * * TODO probably hooked as a boolean, one successful the other not */ -export class GraphError extends Error { -} +export class GraphError extends Error {} +export class RuleError extends Error {} /** * Data associated with a single vertex. @@ -270,14 +270,14 @@ export class Graph extends Ray { * * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. */ - domain = (): Ray => this.___domain(this.inputs()); + get domain(): Ray { return this.___domain(this.inputs()) }; /** * Return the domain of the graph. * * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. */ - codomain = (): Ray => this.___domain(this.outputs()); + get codomain(): Ray { return this.___domain(this.outputs()) }; /** * Return the :class:`VData` associated with vertex id `v`. @@ -779,12 +779,9 @@ export class Matches extends Ray { __next__ = (): Ray => { throw new NotImplementedError(); } } -export class RuleError extends Ray { -} - export class Rule extends Ray { - get lhs(): Ray { throw new NotImplementedError(); } - get rhs(): Ray { throw new NotImplementedError(); } + get lhs(): Graph { throw new NotImplementedError(); } + get rhs(): Graph { throw new NotImplementedError(); } /** * TODO: Put the name on each side of the rule, not the '-' hacky thing @@ -792,10 +789,46 @@ export class Rule extends Ray { get name(): Ray { throw new NotImplementedError(); } get equiv(): Ray { throw new NotImplementedError(); } - __init__ = (lhs = Graph, rhs = Graph, name = str(''), equiv = bool(True)): Ray => { throw new NotImplementedError(); } + __init__ = (name = str(''), equiv = bool(True)): Ray => { + // TODO: Maybe just move exception to a method on this thing + + if (this.lhs.domain !== this.rhs.domain) // TODO: !== + throw new RuleError(`Inputs must match on LHS and RHS of rule (${this.rhs.domain} != ${this.lhs.domain})`); + + if (this.lhs.codomain !== this.rhs.codomain) + throw new RuleError(`Outputs must match on LHS and RHS of rule (${this.rhs.codomain} != ${this.lhs.codomain})`) + + + throw new NotImplementedError(); + + } + copy = (): Ray => { throw new NotImplementedError(); } - converse = (): Ray => { throw new NotImplementedError(); } - is_left_linear = (): Ray => { throw new NotImplementedError(); } + + // TODO: Could put this on ray, generalize to swapping + converse = (): Rule => { + // TODO remove this hacky thing - just tries to us -a / a + const name = this.name.as_string().startsWith('-') ? this.name.substring(1) : `-${this.name}`; + + const converse: Rule = this.copy().cast(); // TODO equiv=True? + converse.name = name; + + // TODO: Wont work, we just should swap initial/terminal;\ + //swap?? or change direction.. + // const swap = converse.rhs; + // converse.rhs = converse.lhs; + // converse.lhs = swap; + return converse; + } + + /** + * Returns True if boundary on lhs embeds injectively + */ + is_left_linear = (): Ray => { + // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading + return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray().force() + .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. + } } export class RewriteState extends Ray { From 0b5ee47cae2be8291300f0638331bc8f16c58d24 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 6 Jan 2024 14:40:17 +0100 Subject: [PATCH 012/138] 2024/02/06 - Some translations --- src/@orbitmines/explorer/Ray.ts | 1 + .../external/implementations/chyp/Chyp.ts | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 4ddea68..d35947d 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -221,6 +221,7 @@ export class Ray return RayType.VERTEX; } + // TODO: Perhaps locally cache count?? - no way to ensure globally coherenct count = (): Ray => { throw new NotImplementedError() } // TODO; Could return the ignorant reference to both instances, or just the result., .. diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index 9fb5a5d..efbc457 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -78,6 +78,17 @@ export const VType = JS.Iterable([str, None]); export class GraphError extends Error {} export class RuleError extends Error {} +/** + * Used for debugging (the matcher) + */ +const DEBUG = true; // TODO; Generalize +const log = (s: string) => { + if (!DEBUG) + return; + + console.log(s); +} + /** * Data associated with a single vertex. */ @@ -829,6 +840,70 @@ export class Rule extends Ray { return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray().force() .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. } + + /** + * Do double-pushout rewriting + * + * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. + * @param match + */ + dpo = (match: Match): Ray => { + // if (!this.is_left_linear()) + // throw new NotImplementedError("Only left linear rules are supported for now") + + const rewritten_graph: Graph = match.codomain.copy(); + + // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? + + // Computes the push complement ?? (just the thing we're replacing right?) + // TODO: Removes the match from the copy? + this.lhs.edges().all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); + + const inputs = []; + const outputs = []; + + this.lhs.vertices().all(rule_vertex => { + const match_vertex = match.vertex_map[rule_vertex]; + + if (!this.lhs.is_boundary(rule_vertex)) { + rewritten_graph.remove_vertex(match_vertex); + return; + } + + const rule_input = this.lhs.vertex_data(rule_vertex).in_indices; + const rule_output = this.lhs.vertex_data(rule_vertex).out_indices; + + if (rule_input.count() === 1 && rule_output === 1) { + const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); + + if (match_input.count() !== 1 && match_output.count() !== 1) + throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); + + inputs[rule_vertex] = match_input[0]; + outputs[rule_vertex] = match_output[0]; + } else if (rule_input.count() > 1 || rule_output.count() > 1) { + throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); + } + }) + + // Embed Rule.rhs into rewritten_graph + const replacement = new Match(this.rhs, rewritten_graph); + + return replacement; + } + + /** + * Apply the given rewrite r to at match m and return the first result + * + * This is a convience wrapper for `dpo` for when the extra rewrite data isn't needed. + */ + rewrite = (match: Match): Graph => { + // TODO: except StopIteration: + // raise RuntimeError("Rewrite has no valid context") + + const result: Match = this.dpo(match).first().cast(); + return result.codomain; + } } export class RewriteState extends Ray { From f007ac125e3f564dbad28b45bcecb791d5698123 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 6 Jan 2024 15:58:56 +0100 Subject: [PATCH 013/138] 2024/02/06 - Some translations --- .../external/implementations/chyp/Chyp.ts | 152 +++++++++++++++++- 1 file changed, 149 insertions(+), 3 deletions(-) diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index efbc457..c4c28d1 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -175,6 +175,11 @@ export class VData extends Ray { throw new NotImplementedError(); } + + fresh = (): VData => { + // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. + + } } /** @@ -469,7 +474,50 @@ export class Graph extends Ray { */ merge_vertices = (v = int, w = int): Ray => this.vertex_data(v).merge(this.vertex_data(w)); - explode_vertex = (v = int): Ray => { throw new NotImplementedError(); } + /** + * Split a vertex into copies for each input, output, and tentacle. + * + * This is used for computing pushout complements of rules that aren't left-linear. + * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). + * + * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. + * + * @param v Integer identifier of vertex to be exploded. + */ + explode_vertex = (v = int): Ray => { + const vertex = this.vertex_data(v); + + // TODO; This just seems like another copy which minor changes + + const next_inputs = empty(); + const next_outputs = empy(); + + const fresh = (j: VData) => { + + } + + // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. + // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs()]) + // TODO: Basically a copy, and replace this one vertex + + // Where the original vertex is the target of a hyperedge, replace its occurence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. + + vertex.in_edges.all(e => { + const edge: EData = e.cast(); + + edge.t = edge.t + .map(target => { + if (target === v) + return target; + + next_inputs.add(this.add_vertex(vertex.fresh())) + this.vertex_data(target).in_edges.add(edge); + }) + }) + + } + + insert_id_after = (v = int): Ray => { throw new NotImplementedError(); } tensor = (other = Graph): Ray => { throw new NotImplementedError(); } __mul__ = (other = Graph): Ray => { throw new NotImplementedError(); } @@ -765,15 +813,105 @@ export class MainWindow extends Ray { build_menu = (): Ray => { throw new NotImplementedError(); } } +// TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? export class Match extends Ray { + + get domain(): Graph { throw new NotImplementedError(); } + get codomain(): Graph { throw new NotImplementedError(); } + get vertex_map(): Ray { throw new NotImplementedError(); } + get vertex_image(): Ray { throw new NotImplementedError(); } + get edge_map(): Ray { throw new NotImplementedError(); } + get edge_image(): Ray { throw new NotImplementedError(); } + __init__ = (): Ray => { throw new NotImplementedError(); } - __str__ = (): Ray => { throw new NotImplementedError(); } + __str__ = (): Ray => { + // (f'\tVertex map: {str(self.vertex_map)}' + // + f'\n\tEdge map: {str(self.edge_map)}') + // TODO + throw new NotImplementedError(); } // Implemented on Ray // TODO; doesnt copy the graphs at domain/codomain // copy = (): Ray => { throw new NotImplementedError(); } - try_add_vertex = (domain_vertex = int, codomain_vertex = int): Ray => { throw new NotImplementedError(); } + /** + * Try to map `domain_vertex` to `codomain_vertex`. + * + * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. + * + * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. + */ + try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { + + // If the vertex is already mapped, only check the new mapping is consistent with the current match. + if (this.vertex_map.includes(domain_vertex)) { + log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) + return this.vertex_map[domain_vertex] === codomain_vertex; + } + + // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. + // TODO: This should all be redundant, probably removed ... + + // Ensure the mapping preserves vertex type. + if (domain_vertex.vtype !== codomain_vertex.vtype) { + log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); + + return bool(False); + } + + // Ensure the mapping preserves vertex size. + if (domain_vertex.size !== codomain_vertex.size) { + log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) + return bool(False); + } + + // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. + if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { + log('Vertex failed: codomain vertex is boundary but domain vertex is not.') + return bool(False); + } + + // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. + if (this.vertex_image.includes(codomain_vertex)) { + // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. + if (!domain_vertex.is_boundary()) { + log('Vertex failed: non-injective on interior vertex.') + return bool(False); + } + + // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. + if (this.vertex_image.any(([mapped_vertex, image_vertex]) => + image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! + )) { + log('Vertex failed: non-injective on interior vertex.') + return bool(False); + } + + return bool(False); + } + + // If a new and consistent map is found, add it to the vertex map of this match. + this.vertex_map[domain_vertex] = codomain_vertex + this.vertex_image.add(codomain_vertex) + + // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. + + if (!domain_vertex.is_boundary()) { + if (domain_vertex.in_edges.count() !== codomain_vertex.in_edges.count()) { + log('Vertex failed: in_edges cannot satisfy gluing conditions.') + return bool(False) + } + if (domain_vertex.out_edges.count() !== codomain_vertex.out_edges.count()) { + log('Vertex failed: in_edges cannot satisfy gluing conditions.') + return bool(False) + } + } + + // If a new consistent map is added that satisfies the gluing conditions, we are successful. + log('Vertex success.') + return bool(True); + } + try_add_edge = (domain_edge = int, codomain_edge = int): Ray => { throw new NotImplementedError(); } domain_neighbourhood_mapped = (vertex = int): Ray => { throw new NotImplementedError(); } map_scalars = (): Ray => { throw new NotImplementedError(); } @@ -782,6 +920,14 @@ export class Match extends Ray { is_surjective = (): Ray => { throw new NotImplementedError(); } is_injective = (): Ray => { throw new NotImplementedError(); } is_convex = (): Ray => { throw new NotImplementedError(); } + + /** + * TODO Not implemented;; + * # def cod_nhd_mapped(self, cod_v: int): + * # """Returns True if nhd(cod_v) is the range of emap""" + * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and + * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) + */ } export class Matches extends Ray { From eb251554f5e6449e68de72c9f909744be8f457c9 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sun, 7 Jan 2024 13:04:57 +0100 Subject: [PATCH 014/138] 2024/02/07 - Some translations --- src/@orbitmines/explorer/Ray.ts | 12 +- .../external/implementations/chyp/Chyp.ts | 166 +++++++++++++++--- 2 files changed, 153 insertions(+), 25 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index d35947d..08689dc 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -96,9 +96,14 @@ export class Ray js: () => Option; // TODO: Could make a case that setting the terminal is more of a map, defaulting/first checking the terminal before additional functionality is mapped over that. - initial: () => Option; - vertex: () => Option; - terminal: () => Option; + // initial: () => Option; + // vertex: () => Option; + // terminal: () => Option; + + // TODO: Just temp for quick impl + get initial(): Ray {} + get vertex(): Ray {} + get terminal(): Ray {} self = (): Option => this.vertex(); @@ -237,6 +242,7 @@ export class Ray map = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } all = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } filter = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } + clear = (): Ray => { throw new NotImplementedError(); } *traverse(): Generator {} diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index c4c28d1..d4cc8dc 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -27,6 +27,7 @@ import {Option} from "../../../js/utils/Option"; * * TODO: Runtime errors as rays * + * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph */ export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; @@ -173,12 +174,41 @@ export class VData extends Ray { // this.initial().force().equivalent(other.initial().force()); // this.terminal().force().equivalent(other.initial().force()); + /* + + vd = self.vertex_data(v) + # print("merging %s <- %s" % (v, w)) + + # Where vertex `w` occurs as an edge target, replace it with `v` + for e in self.in_edges(w): + ed = self.edge_data(e) + ed.t = [v if x == w else x for x in ed.t] + vd.in_edges.add(e) + + # Where vertex `w` occurs as an edge source, replace it with `v` + for e in self.out_edges(w): + ed = self.edge_data(e) + ed.s = [v if x == w else x for x in ed.s] + vd.out_edges.add(e) + + # Wherever `w` occurs on the graph boundary, replace it with `v` + self.set_inputs([v if x == w else x for x in self.inputs()]) + self.set_outputs([v if x == w else x for x in self.outputs()]) + + # Remove references to `w` from the graph + self.remove_vertex(w) + + */ + throw new NotImplementedError(); } fresh = (): VData => { // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. + // vtype=vd.vtype, size=vd.size, + // x=vd.x, y=vd.y, value=vd.value + } } @@ -490,39 +520,101 @@ export class Graph extends Ray { // TODO; This just seems like another copy which minor changes const next_inputs = empty(); - const next_outputs = empy(); - - const fresh = (j: VData) => { + const next_outputs = empty(); + + const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process + vertex: VData, + boundary: (vertex: VData) => Ray, + next_boundary: Ray + ) => { + // TODO: It's just a duplicated process for vertex/edge since their definition is separataed + + // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. + // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs()]) + // TODO: Basically a copy, and replace this one vertex + + // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. + boundary(vertex).all(e => { + const edge: EData = e.cast(); + + edge.t = edge.t + .map(target => { + if (target === v) + return target; + + const fresh_vertex = vertex.fresh(); + next_boundary.add(this.add_vertex(fresh_vertex)) + boundary(fresh_vertex).add(edge); + }) + }); } - // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. - // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs()]) - // TODO: Basically a copy, and replace this one vertex + // TODO: It's always just duplicated for both ends, + __temp(vertex, (vertex) => vertex.in_edges, next_inputs); + __temp(vertex, (vertex) => vertex.out_edges, next_outputs); + + // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. + vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal + vertex.out_edges.clear(); - // Where the original vertex is the target of a hyperedge, replace its occurence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. + // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). + this.remove_vertex(vertex, true); - vertex.in_edges.all(e => { - const edge: EData = e.cast(); + return [next_inputs, next_outputs]; + } - edge.t = edge.t - .map(target => { - if (target === v) - return target; - next_inputs.add(this.add_vertex(vertex.fresh())) - this.vertex_data(target).in_edges.add(edge); - }) - }) + insert_id_after = (v = int): Ray => { throw new NotImplementedError(); } + + + tensor = (other: Graph): Ray => { throw new NotImplementedError(); } + + /** + * Sequentially compose this graph in-place with another. + * + * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. + */ + compose = (other: Graph): Ray => { + // TODO Just matching outputs and inputs.. + + const a = this; + const b = other; + + // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" + const compose: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] + + // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. + + if (compose.initial.count() !== compose.terminal.count()) + throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed + } + /** + * Return the tensor product of this graph with another. + * + * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them + */ + __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); - insert_id_after = (v = int): Ray => { throw new NotImplementedError(); } - tensor = (other = Graph): Ray => { throw new NotImplementedError(); } - __mul__ = (other = Graph): Ray => { throw new NotImplementedError(); } - compose = (other = Graph): Ray => { throw new NotImplementedError(); } - __rshift__ = (other = Graph): Ray => { throw new NotImplementedError(); } + /** + * Return the composition of the current graph with `other`. + * + * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. + * @param other + */ + __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); + + /** + * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer + */ + ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { + const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. + something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? + return a_copy; // Could generalize to either end + } /** * Set the `highlight` flag for a set of vertices and edges. @@ -689,6 +781,36 @@ export class Chyp extends Ray { return graph; } + /** + * # def wide_id() -> Graph: + * # return gen("id", 1, 1) + * + * # def id_perm(p: List[int]) -> Graph: + * # g = Graph() + * # size = len(p) + * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] + * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] + * + * # for i in range(size): + * # y = i - (size-1)/2 + * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) + * + * # g.set_inputs(inputs) + * # g.set_outputs(outputs) + * + * # return g + */ + + /** + * Return a graph corresponding to a vertex size redistribution. + * + * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. + * + * More generally, a conversion can be done between different lists of sizes, for some vertex type. + */ + redistributer = (domain = list, codomain = list) => { + + } } export class CodeView extends Ray { From fc42941a3a26d73869bc1e520e1ede128313f173 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sun, 7 Jan 2024 15:47:58 +0100 Subject: [PATCH 015/138] 2024/02/07 - Some translations --- src/@orbitmines/explorer/Ray.ts | 31 +++++++++++ .../external/implementations/chyp/Chyp.ts | 51 ++++++++++++++++++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 08689dc..b0dbe1d 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -244,6 +244,37 @@ export class Ray filter = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } clear = (): Ray => { throw new NotImplementedError(); } + // TODO: Generalize these functions to: + // + // TODO: +default, in the case of Initial/Terminal = Option.None, to which the default sometimes is nothing. Or in the case of min/max it's 0. + + + // TODO: being called min.x needs to return the min value within that entire structure. + + // [this.vertices().x.max(), this.edges().x.max()].max() + // [this.vertices().x.min(), this.edges().x.max()].max() + min = (_default: 0): Ray => { throw new NotImplementedError(); } + max = (_default: 0): Ray => { throw new NotImplementedError(); } + + // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS + apply = (func: Ray) => { + + // TODO: Combine into generalized [x, min/max()] - preserve terminal/initial structure + // TODO: ray#apply. + // TODO: FROM COMPOSER + /** + * const func = [min(), '', max()] + * + * const [min_x, max_x] = [ + * // Compute the min x-coordinate of the edges and vertices in the other graph. + * compose.terminal.x.min(), // min_other + * + * // Compute the max x-coordinate of the edges and vertices in this graph. + * compose.initial.x.max(), // max_self + * ] + */ + } + *traverse(): Generator {} /** diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index d4cc8dc..9339ee4 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -586,8 +586,55 @@ export class Graph extends Ray { // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. - if (compose.initial.count() !== compose.terminal.count()) - throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed + // TODO: This is just again an equivalence type check on the ends of the ray + + { + if (compose.initial.count() !== compose.terminal.count()) + throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed + + /** + * for output_id, input_id in zip(self_outputs, other_inputs): + * output_data = self.vertex_data(output_id) + * input_data = other.vertex_data(input_id) + * if output_data.vtype != input_data.vtype: + * if not (output_data.infer_type or input_data.infer_type): + * raise GraphError( + * f'Codomain {self.codomain()} does not ' + * + f'match domain {other.domain()}' + * ) + * if output_data.size != input_data.size: + * if not (output_data.infer_size or input_data.infer_size): + * raise GraphError( + * f'Codomain {self.codomain()} does not ' + * + f'match domain {other.domain()}' + * ) + */ + } + + /** + * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. + */ + + // Compute the max x-coordinate of the edges and vertices in this graph. + + // TODO: Again, recursively going through everything defined on the initial side (outputs) + // Shift all vertices and edges of this graph below the x-axis. + compose.initial.x -= + compose.initial.x.max(); // max_self + + // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] + compose.terminal.x -= + compose.terminal.x.min(); // min_other + + // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. + /** + * plug1 = self.outputs() + * plug2 = [vmap[v] for v in other.inputs()] + * + * if len(plug1) != len(plug2): + * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' + * + f'outputs into one with {len(plug2)} inputs') + */ } From fe030428ce8410d3134c800033238105b9d3fee3 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sun, 7 Jan 2024 16:07:50 +0100 Subject: [PATCH 016/138] 2024/02/07 - Some translations --- .../external/implementations/chyp/Chyp.ts | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index 9339ee4..b823f48 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -567,8 +567,37 @@ export class Graph extends Ray { insert_id_after = (v = int): Ray => { throw new NotImplementedError(); } + /** + * Take the monoidal product of this graph in-place with another. + * + * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. + * + * @param other + * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. + */ + tensor = (other: Graph, layout: boolean = true): Ray => { + + const a = this; + const b = other; - tensor = (other: Graph): Ray => { throw new NotImplementedError(); } + const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] + + tensor.initial.y -= + tensor.initial.y.max(); // max_self + + tensor.terminal.y -= + (layout ? tensor.terminal.y.min() : 0) + 1; // min_other TODO: Why + 1 ? + + /** + * # self.set_inputs(self.inputs() + [vmap[v] for v in other.inputs()]) + * # self.set_outputs(self.outputs() + [vmap[v] for v in other.outputs()]) + * + * # Add the inputs and outputs of the other graph to this one. + * self.add_inputs([vmap[v] for v in other.inputs()]) + * self.add_outputs([vmap[v] for v in other.outputs()]) + */ + // TODO: Add equivalence/reference on the inputs/output extremes. + } /** * Sequentially compose this graph in-place with another. @@ -588,6 +617,8 @@ export class Graph extends Ray { // TODO: This is just again an equivalence type check on the ends of the ray + // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs + { if (compose.initial.count() !== compose.terminal.count()) throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed From a8fd7f2e015584ca20b47196078928f6118c9ab9 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sun, 7 Jan 2024 16:15:26 +0100 Subject: [PATCH 017/138] test --- .../implementations/chyp/ChypCanvas.tsx | 56 +++++++++++++++---- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx index 12d47b4..ab77ade 100644 --- a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx @@ -31,7 +31,6 @@ const ChypCanvas = (
@@ -57,6 +56,7 @@ const ChypCanvas = ( {/**/} + {/* Being able to reference any part from within the structure - self-compiling */} {/**/} {/* */} @@ -65,16 +65,52 @@ const ChypCanvas = ( {/* /!**!/*/} {/**/} + {/* Continuation expanded */} + {/**/} + {/* */} + + {/* */} + {/* */} + {/* */} + {/* /!**!/*/} + {/**/} + + - - - - - - {/**/} + + + + + + + + + + + + + + + + + {/**/} + {/* */} + {/* */} + {/* */} + + {/* */} + {/* */} + {/* */} + {/**/} +
@@ -90,7 +126,7 @@ export const ChypExplorer = ( const listener: IEventListener = {} - return + return } export default ChypCanvas; \ No newline at end of file From 1909bdc6fd12f3ce206a3152fe6206c8749c189a Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sun, 7 Jan 2024 17:12:03 +0100 Subject: [PATCH 018/138] Some interface playground --- .../explorer/OrbitMinesExplorer.tsx | 8 +- src/@orbitmines/explorer/Ray.ts | 12 ++ .../implementations/chyp/ChypCanvas.tsx | 183 ++++++++++-------- .../external/implementations/chyp/examples.ts | 76 ++++++++ 4 files changed, 189 insertions(+), 90 deletions(-) create mode 100644 src/@orbitmines/external/implementations/chyp/examples.ts diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index dd0b74a..2b2bfc9 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -16,7 +16,7 @@ import {Children, value} from "../../lib/typescript/React"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import {NotImplementedError} from "./errors/errors"; -const add = (a: number[], b: number[]): [number, number, number] => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; +export const add = (a: number[], b: number[]): [number, number, number] => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; export const torus = { // Radius of the torus, from the center of the torus to the center of the tube. Default is 1. @@ -201,7 +201,7 @@ export const BinarySuperposition = ({ position = [0, 0, 0], scale = 1.5 }: any) * * TODO; Generalize to Ray - should be embedded on the vertex, or on another layer of description, where the interface is a rewrite rule */ -type InterfaceOptions = { +export type InterfaceOptions = { position?: [number, number, number], rotation?: [number, number, number], scale?: number, @@ -215,7 +215,8 @@ type Options = { export const AutoRenderedRay = (ray: Omit & InterfaceOptions & { length?: number // basically .length -} & Partial) => { + children?: any +}) => { const { length = 1, children @@ -267,7 +268,6 @@ export const SimpleRenderedRay = ( ..._.pick(ray, 'position', 'rotation', 'scale', 'color') } - console.log(_default) const _Continuation = ({ color = torus.color, ...options }: InterfaceOptions) => = () => T; @@ -235,6 +236,17 @@ export class Ray static dirty_store: { [label: string]: object } = {} get store(): any { return Ray.dirty_store[this.label] ??= {} } + o = (o: InterfaceOptions): Ray => { return this.with('options', o); } + get o_(): InterfaceOptions { return this.store['options'] ?? { + + } + } + + with = (key: string, any: any): Ray => { + this.store[key] = any; + return this; + } + debug = (c: { [label: string]: object | undefined }): object => { if (c[this.label] !== undefined) return c[this.label]!; diff --git a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx index ab77ade..1fab79d 100644 --- a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx @@ -1,9 +1,102 @@ -import React from "react"; +import React, {useRef, useState} from "react"; import IEventListener, {mergeListeners} from "../../../js/react/IEventListener"; import {VisualizationCanvas} from "../../../explorer/Visualization"; -import {AutoRenderedRay, BinarySuperposition, Loop, SimpleRenderedRay} from "../../../explorer/OrbitMinesExplorer"; -import {RayType} from "../../../explorer/Ray"; +import {add, AutoRenderedRay, BinarySuperposition, Loop, SimpleRenderedRay} from "../../../explorer/OrbitMinesExplorer"; +import {empty_vertex, js, Ray, RayType} from "../../../explorer/Ray"; import {Center} from "@react-three/drei"; +import {Option} from "../../../js/utils/Option"; +import {useHotkeys} from "../../../js/react/hooks/useHotkeys"; + +const Interface = () => { + const ref = useRef(); + const hotkeys = useHotkeys(); + + const scale = 1.5; + const i = 20 * scale; + + const [selection, setSelection] = useState( + empty_vertex().as_reference().o({ + position: [0, 0, 0], + scale + }) + ); + + const [rays, setRays] = useState([selection]); + + hotkeys.set(...[ + { + combo: "arrowright", global: true, label: "", onKeyDown: () => { + + const next = js("A").as_reference().o({ + position: add(selection.o_.position ?? [0, 0, 0], [i * 2, 0, 0]), + scale + }); + setSelection(next); + setRays([...rays, next]); + + // selection.continues_with( + + // ); + + console.log(rays); + } + }, + { + combo: "arrowleft", global: true, label: "", onKeyDown: () => { + + rays.pop(); + setSelection(rays[rays.length - 1]); + + // selection.continues_with( + + // ); + + console.log(rays); + } + }, + { + combo: "arrowup", global: true, label: "", onKeyDown: () => { + + setRays(rays.flatMap(ray => [ + ray, + js("A").as_reference().o({ + ...ray.o_, + position: add(ray.o_.position ?? [0, 0, 0], [0, i * 2, 0]) + }), + js("A").as_reference().o({ + ...ray.o_, + position: ray.o_.position, + rotation: [0, 0, Math.PI / 2] + }), + js("A").as_reference().o({ + ...ray.o_, + position: add(ray.o_.position ?? [0, 0, 0], [0, i * 2, 0]), + rotation: [0, 0, Math.PI / 2] + }) + ])); + + selection.o({...selection.o_, position: add(selection.o_.position ?? [0, 0, 0], [0, i * 2, 0])}) + setSelection(selection) + + // selection.continues_with( + + // ); + + console.log(rays); + } + } + ]); + + return <> +
+ + + {rays.map(ray => )} + + {/**/} +
+ +} /** * TODO: Import .chyp files @@ -20,8 +113,6 @@ const ChypCanvas = ( } - const scale = 1.5; - return
{/**/} {/* */} @@ -30,88 +121,8 @@ const ChypCanvas = ( -
- - {/* Iterator */} - {/**/} - {/* */} - {/* */} - {/**/} - - {/* Grid/Dictionary/... */} - {/**/} - {/* */} - {/* */} - {/* */} - {/* */} - {/* */} - {/**/} - - {/* Loop memory */} - {/**/} - {/* */} - {/* */} - {/**/} - - - - {/* Being able to reference any part from within the structure - self-compiling */} - {/**/} - {/* */} - {/* */} - {/* /!**!/*/} - {/**/} - - {/* Continuation expanded */} - {/**/} - {/* */} - - {/* */} - {/* */} - {/* */} - {/* /!**!/*/} - {/**/} - - - - - - - - - - - - - - - - - - - - - {/**/} - {/* */} - {/* */} - {/* */} - - {/* */} - {/* */} - {/* */} - {/**/} - -
+
} diff --git a/src/@orbitmines/external/implementations/chyp/examples.ts b/src/@orbitmines/external/implementations/chyp/examples.ts new file mode 100644 index 0000000..581b15c --- /dev/null +++ b/src/@orbitmines/external/implementations/chyp/examples.ts @@ -0,0 +1,76 @@ +{/* Iterator */} +{/**/} +{/* */} +{/* */} +{/**/} + +{/* Grid/Dictionary/... */} +{/**/} +{/* */} +{/* */} +{/* */} +{/* */} +{/* */} +{/**/} + +{/* Loop memory */} +{/**/} +{/* */} +{/* */} +{/**/} + + + +{/* Being able to reference any part from within the structure - self-compiling */} +{/**/} +{/* */} +{/* */} +{/* /!**!/*/} +{/**/} + +{/* Continuation expanded */} +{/**/} +{/* */} + +{/* */} +{/* */} +{/* */} +{/* /!**!/*/} +{/**/} + + +{/**/} +{/* */} +{/* */} +{/* */} +{/* */} + +{/* */} +{/* */} +{/* */} +{/* */} + +{/* */} +{/* */} + +{/* */} + +{/**/} + +{/**/} +{/* */} +{/* */} +{/* */} + +{/* */} +{/* */} +{/* */} +{/**/} From 134dd728c6a0cd7b088854f3bfcb83cca8179b66 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 8 Jan 2024 20:54:33 +0100 Subject: [PATCH 019/138] 2024/02/08 - Moving around some Ray definitions --- .../explorer/OrbitMinesExplorer.tsx | 56 ++-- src/@orbitmines/explorer/Ray.ts | 311 +++++++++--------- .../external/implementations/chyp/Chyp.ts | 93 ++++-- src/@orbitmines/js/utils/Option.ts | 52 --- src/@orbitmines/js/utils/match.ts | 142 -------- 5 files changed, 249 insertions(+), 405 deletions(-) delete mode 100644 src/@orbitmines/js/utils/Option.ts delete mode 100644 src/@orbitmines/js/utils/match.ts diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index dd0b74a..239a4e8 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -309,7 +309,7 @@ export const SimpleRenderedRay = ( // In principle, this should be anything, this is just for the initial setup export const RenderedRay = ( - props: { reference: Option } & { position?: [number, number, number], initial?: [number, number, number], terminal?: [number, number, number], scale?: number, color?: string } + props: { reference: Ray } & { position?: [number, number, number], initial?: [number, number, number], terminal?: [number, number, number], scale?: number, color?: string } ) => { const { position = [0, 0, 0], @@ -336,28 +336,28 @@ export const RenderedRay = ( /** * [ |--] */ - if (vertex.vertex().is_none()) { + if (vertex.vertex.is_none()) { return } else { - const possible_continuations = vertex.vertex().force(); + const possible_continuations = vertex.vertex.force(); if (!possible_continuations.as_reference().is_terminal()) return // - // if (vertex.terminal().force().store.rendered) + // if (vertex.terminal.force().store.rendered) // return <> return } } case RayType.TERMINAL: { - if (vertex.vertex().is_none()) { + if (vertex.vertex.is_none()) { return } else { - const possible_continuations = vertex.vertex().force(); + const possible_continuations = vertex.vertex.force(); // if (!possible_continuations.as_reference().is_initial()) // return @@ -365,7 +365,7 @@ export const RenderedRay = ( // return } } @@ -374,7 +374,7 @@ export const RenderedRay = ( return // throw 'Not Implemented' - return ray.as_reference().as_option(), None: () => Option.None })} /> + return ray.as_reference(), None: () => Ray.None })} /> } case RayType.VERTEX: { const tilt = -10; // TODO; Generally should use some equivalencing in the 3d-frames for this once setup is in place (perpsective/camera) if in threejs.. @@ -404,14 +404,14 @@ export const RenderedRay = ( // const right = add(position, [20, 0, 0]); // // return <> - // + // // // {/* Line now starts in the center of the torus tube */} // // {/**/} // // - // + // // // } @@ -544,8 +544,8 @@ export const RenderedRay = ( {/**/} {/**/} - {/**/} - + {/**/} + {/* Line now starts in the center of the torus tube */} {/*{isVertical*/} @@ -569,7 +569,7 @@ export const RenderedRay = ( {/*{<>*/} - {/* */} + {/* */} {/* /!* Line now starts in the center of the torus tube *!/*/} {/* */} @@ -583,11 +583,11 @@ export const RenderedRay = ( {/* : */} {/* }*/} - {/* */} + {/* */} {/*}*/} - + {/* { const ref = useRef(); - const [selection, setSelection] = useState>( - empty_vertex().as_reference().as_option() + const [selection, setSelection] = useState( + empty_vertex().as_reference() ); - const [controls, setControls] = useState>( - empty().as_reference().as_option() + const [controls, setControls] = useState( + empty().as_reference() ); const { @@ -701,7 +701,7 @@ const InterfaceObject = ({ combo: "arrowright", global: true, label: "", onKeyDown: () => { const next = selection.force().continues_with( new Ray({ js: () => Option.Some("A") }).as_reference() - ).as_option(); + ); setSelection(next) } @@ -891,7 +891,7 @@ const Test2 = ({ ray, position }: { ray: Ray, position: [number, number, number] {[...ray.traverse()].map((vertex, i) => ( - + ))} ) @@ -911,14 +911,14 @@ const Test2 = ({ ray, position }: { ray: Ray, position: [number, number, number] // * // * So in the case of [0, 1], this would be a reference to the Iterator, in the case of 1/2/3/4/5, a reference to their respective values. // */ -// const reference = vertex.vertex(); +// const reference = vertex.vertex; // // if (reference.is_some()) { -// if (reference.force().vertex().is_none()) +// if (reference.force().vertex.is_none()) // continue; // // // This would be the Iterator, or the numbers respectively. -// const dereferenced = reference.force().vertex().force(); +// const dereferenced = reference.force().vertex.force(); // /** // * Can again be any of these: // * [--|--] @@ -932,13 +932,13 @@ const Test2 = ({ ray, position }: { ray: Ray, position: [number, number, number] // // console.log(' traversing nested reference'); // for (let nested of reference.force().traverse()) { -// const nested_reference = nested.vertex(); +// const nested_reference = nested.vertex; // // if (nested_reference.is_some()) { -// if (nested_reference.force().vertex().is_none()) +// if (nested_reference.force().vertex.is_none()) // continue; // -// const nested_dereferenced = nested_reference.force().vertex().force(); +// const nested_dereferenced = nested_reference.force().vertex.force(); // // console.log('type:', nested_reference.force().toString()); // console.log('structure at', nested_dereferenced.js().force()) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index b0dbe1d..e2d4af3 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,69 +1,29 @@ import {enumeration, MemberType, none, TaggedUnion} from "../../@orbitmines/js/utils/match"; -import {Option} from "../js/utils/Option"; import _ from "lodash"; -import {compile} from "sass"; import {NotImplementedError} from "./errors/errors"; -export type ParameterlessFunction = () => T; - -// /** -// * Defines some flexibility to ignore a lot of the JavaScript specifics (we're not trying to model JavaScript here). -// */ -// export type ArbitraryObj = { -// Ref: (ref: Option) => typeof ref, -// Fn: (fn: ParameterlessFunction>) => typeof fn, -// }; -// export type ArbitraryImpl = { -// none_or: (or: (obj: T) => Result) => Arbitrary, -// resolve: () => Option, -// } -// export type Arbitrary = MemberType, ArbitraryImpl>>; -// -// export const Arbitrary = enumeration, ArbitraryImpl>({ -// Ref: (ref: Option) => ref, -// Fn: (fn: ParameterlessFunction>) => fn, -// }, self => class { -// resolve = (): any => self.match({ -// Ref: (ref) => ref, -// Fn: (fn) => fn(), -// }) -// -// none_or = (or: (obj: any) => any): Arbitrary => self.resolve().match({ -// Some: (obj) => or(obj), -// None: () => Arbitrary.Ref(Option.None) -// }) -// }); - -/** - * Replace "Ray" for "AbstractDirectionality" in case "Ray" doesn't suit you. - */ -export interface AbstractDirectionality { - initial(): T - vertex(): T - terminal(): T -} - // SHOULDNT CLASSIFY THESE? export enum RayType { REFERENCE = ' | ', - INITIAL = ' |--', - TERMINAL = '--| ', + INITIAL = ' |-?', + TERMINAL = '?-| ', VERTEX = '--|--', } -// TODO: Option = Ray - -export type Arbitrary = (...args: any[]) => Option | T; +export type ParameterlessFunction = () => T; +export type Arbitrary = (...args: any[]) => T; /** * https://en.wikipedia.org/wiki/Homoiconicity */ export interface PossiblyHomoiconic> { - self: Arbitrary + get self(): T; is_reference: () => boolean as_reference: () => T } +export interface AbstractDirectionality { initial: Arbitrary, vertex: Arbitrary, terminal: Arbitrary } + /** * JavaScript wrapper for a mutable value. It is important to realize that this is merely some simple JavaScript abstraction, and anything is assumed to be inherently mutable. * @@ -84,7 +44,7 @@ export interface PossiblyHomoiconic> { * * TODO: Singlke keybind for now to show/hide the ray disambiguation or 'dead edges/..'/ */ -export class Ray +export class Ray // Other possibly names: AbstractDirectionality, ..., ?? implements PossiblyHomoiconic, @@ -93,36 +53,85 @@ export class Ray // TODO: Array, Dictionary... { - js: () => Option; + js: Arbitrary // TODO: Could make a case that setting the terminal is more of a map, defaulting/first checking the terminal before additional functionality is mapped over that. - // initial: () => Option; - // vertex: () => Option; - // terminal: () => Option; - // TODO: Just temp for quick impl - get initial(): Ray {} - get vertex(): Ray {} - get terminal(): Ray {} + protected _initial: Arbitrary; get initial(): Ray { return this._initial(); } set initial(initial: Arbitrary) { this._initial = initial; } + protected _vertex: Arbitrary; get vertex(): Ray { return this._vertex(); } set vertex(vertex: Arbitrary) { this._vertex = vertex; } + protected _terminal: Arbitrary; get terminal(): Ray { return this._terminal(); } set terminal(terminal: Arbitrary) { this._terminal = terminal; } + + get self(): Ray { + if (!this.is_reference()) + throw new NotImplementedError('Preventing bugs, .self is used for the assumption of a reference..'); + + return this.vertex; + }; + set self(self: Arbitrary) { + if (!this.is_reference()) + throw new NotImplementedError('Preventing bugs, .self is used for the assumption of a reference..'); - self = (): Option => this.vertex(); + this.vertex = self; + } [index: number]: Ray; - constructor({ - initial, - vertex, - terminal, + constructor({ initial, vertex, terminal, js, - }: { js?: () => Option } & Partial>> = {}) { - this.initial = initial ?? (() => Option.None); - this.vertex = vertex ?? (() => Option.None); - this.terminal = terminal ?? (() => Option.None); - this.js = js ?? (() => Option.None); + }: { js?: Arbitrary } & Partial> = {}) { + this._initial = initial ?? Ray.None; + this._vertex = vertex ?? Ray.None; + this._terminal = terminal ?? Ray.None; + this.js = js ?? Ray.None; + } + + /** [ |-?] */ is_initial = (): boolean => this.self.is_some() && this.self.initial.is_none(); + /** [--|--] */ is_vertex = (): boolean => !this.is_initial() && !this.is_terminal(); + /** [?-| ] */ is_terminal = (): boolean => this.self.is_some() && this.self.terminal.is_none(); + /** [ | ] */ is_reference = (): boolean => this.is_initial() && this.is_terminal(); + /** [?- -?] */ is_empty = (): boolean => this.self.is_none(); + + get type(): RayType { + /** [ | ] */ if (this.is_reference()) return RayType.REFERENCE; + /** [ |-?] */ if (this.is_initial()) return RayType.INITIAL; + /** [?-| ] */ if (this.is_terminal()) return RayType.TERMINAL; + /** [--|--] */ return RayType.VERTEX; } - as_initial_reference = () => new Ray({ vertex: this.initial, terminal: this.vertex, js: () => Option.Some('initial ref') }).as_reference(); - as_terminal_reference = () => new Ray({ initial: this.vertex, vertex: this.terminal, js: () => Option.Some('terminal ref') }).as_reference(); + /** + * This is basically what breaks the recursive nature of this structure. Imagine a Ray like this: [|--|--|]. There are several ways of interpreting it, either there's a boolean on initial, vertex, terminal; Some 'false' value, says there's nothing there. Some true value says there's something there. - Basically an Option, ..., Maybe as in certain languages. + * + * --- + * + * Another way of interpreting a possible way of implementing it, is no matter how much more detail we would like to ask, the only thing we ever see is the same structure again (if we ignore the difference of us asking about that additional structure, that's still a possible handle on some difference). + * + * As a way of saying/.../assuming: I only 'infinitely' assume it's only this structure, "it seems to halt here". Note that this is necessarily an assumption. No guarantee of this can be made. This is necessarily an equivalence, ..., ignorance. + * + * See more: https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. + * + * --- + * + * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. + */ + is_none = (): boolean => this.self === this; + + static None = (): Ray => { + const self = new Ray({}); + self.self = () => self; + return self; + } + + is_some = (): boolean => !this.is_none(); + + /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ + /** [ | ] -> [?????] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); + /** [ | ] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }).as_reference(); + /** [ | ] -> [??? ] */ as_terminal = () => + new Ray({ initial: this.as_arbitrary(), vertex: () => this.terminal, js: () => 'terminal ref' }).as_reference(); // TODO: These fields as DEBUG + + // as_option = (): Ray => Option.Some(this); + as_arbitrary = (): Arbitrary => () => this; + continues_with = (continues_with: Ray): Ray => { if (!this.as_reference().is_reference()) @@ -136,11 +145,11 @@ export class Ray // TODO: For now just puts it at the vertex, could be done more intelligently const next_vertex = new Ray({ initial: empty().as_arbitrary(), - vertex: () => continues_with.vertex(), + vertex: () => continues_with.vertex, terminal: empty().as_arbitrary() }); - const vertex = this.self().force(); + const vertex = this.self.force(); if (vertex.is_empty()) { console.log('first element') @@ -151,7 +160,7 @@ export class Ray if (!this.is_vertex()) throw 'NotImplemented: Preventing implementation bug; continues_with not called on a vertex'; - const terminal = vertex.terminal().force(); + const terminal = vertex.terminal.force(); if (!terminal.is_empty()) throw 'NotImplemented: Preventing implementation bug; continues_with should be added to the vertex'; @@ -165,7 +174,7 @@ export class Ray // console.log(initial_connection.label) vertex.terminal = next_connection.as_arbitrary(); - const initial = next_vertex.initial(); + const initial = next_vertex.initial; const previous_connection = new Ray({ vertex: () => initial, terminal: next_vertex.as_arbitrary(), @@ -177,7 +186,7 @@ export class Ray next_connection.vertex = previous_connection.as_arbitrary(); previous_connection.vertex = next_connection.as_arbitrary(); - // next_vertex.initial = connection.vertex().force().as_arbitrary(); + // next_vertex.initial = connection.vertex.force().as_arbitrary(); // const connection = new Ray({ // vertex: this.as_arbitrary(), @@ -192,40 +201,10 @@ export class Ray return next_vertex.as_reference(); } - is_initial = (): boolean => this.self().match({ - Some: (self) => self.initial().is_none(), - None: () => false - }); - is_vertex = (): boolean => !this.is_initial() && !this.is_terminal(); - is_terminal = (): boolean => this.self().match({ - Some: (self) => self.terminal().is_none(), - None: () => false - }); - - is_reference = (): boolean => this.is_initial() && this.is_terminal(); - - is_empty = (): boolean => this.self().is_none(); - - as_reference = (): Ray => new Ray({ vertex: () => Option.Some(this) }) // A ray whose vertex references this Ray (ignorantly). - - as_option = (): Option => Option.Some(this); - as_arbitrary = (): Arbitrary => () => this.as_option(); - // TODO NEEDS TO CHECK IF THERE'S SOME INITIAL DEFIEND ; for defining if it has halted equivalent = (other: Ray) => { throw new NotImplementedError(); } - get type(): RayType { - if (this.is_reference()) - return RayType.REFERENCE; - if (this.is_initial()) - return RayType.INITIAL; - if (this.is_terminal()) - return RayType.TERMINAL; - - return RayType.VERTEX; - } - // TODO: Perhaps locally cache count?? - no way to ensure globally coherenct count = (): Ray => { throw new NotImplementedError() } @@ -246,16 +225,22 @@ export class Ray // TODO: Generalize these functions to: // - // TODO: +default, in the case of Initial/Terminal = Option.None, to which the default sometimes is nothing. Or in the case of min/max it's 0. + // TODO: +default, in the case of Initial/Terminal = Ray.None, to which the default sometimes is nothing. Or in the case of min/max it's 0. // TODO: being called min.x needs to return the min value within that entire structure. // [this.vertices().x.max(), this.edges().x.max()].max() // [this.vertices().x.min(), this.edges().x.max()].max() + // TODO: Indicies not corresponding the the directionality defined, are probably on another abstraction layer described this way. More accurately, they're directly connected, and on a separate layer with more stuff in between... + index = (): Ray => { throw new NotImplementedError(); } min = (_default: 0): Ray => { throw new NotImplementedError(); } max = (_default: 0): Ray => { throw new NotImplementedError(); } + // [a, b, c] zip [d, e, f] zip [g, h, i] ... + // [[a,d,g],[b,e,h],[c,f,i]] + zip = (): Ray => { throw new NotImplementedError(); } + // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS apply = (func: Ray) => { @@ -284,19 +269,19 @@ export class Ray async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } // JS.Generator *[Symbol.iterator](): Generator { yield *this.traverse(); } - // JS.AsyncGenerator - as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); - // JS.AsyncIterator - as_async_iterator = (): AsyncIterator => this.as_async_generator(); - // JS.Iterator - as_generator = (): Generator => this[Symbol.iterator](); - // JS.AsyncIterator - as_iterator = (): Iterator => this.as_generator(); - // JS.Array - as_array = (): any[] => [...this]; - // JS.String - toString = (): string => this.as_array().toString(); - as_string = () => this.toString(); + // JS.AsyncGenerator + as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); + // JS.AsyncIterator + as_async_iterator = (): AsyncIterator => this.as_async_generator(); + // JS.Iterator + as_generator = (): Generator => this[Symbol.iterator](); + // JS.AsyncIterator + as_iterator = (): Iterator => this.as_generator(); + // JS.Array + as_array = (): any[] => [...this]; + // JS.String + toString = (): string => this.as_array().toString(); + as_string = () => this.toString(); /** * Quick dirty compilation @@ -308,7 +293,7 @@ export class Ray if (c[this.label] !== undefined) return c[this.label]!; - const of = (option: Option): string => option.match({ + const of = (option: Ray): string => option.match({ Some: (ray) => { ray.debug(c) ; return ray.label; @@ -319,9 +304,9 @@ export class Ray const obj: any = { label: this.label }; c[this.label] = obj; - obj.initial = of(this.initial()); - obj.vertex = of(this.vertex()); - obj.terminal = of(this.terminal()); + obj.initial = of(this.initial); + obj.vertex = of(this.vertex); + obj.terminal = of(this.terminal); obj.type = this.as_reference().type; return obj; @@ -398,6 +383,22 @@ export class Ray } } +// force = (): any => self.match({ +// Some: (a) => a, +// None: () => { throw new Error('Expected Some(value) to be present but found None.') } +// }); +// +// default = (fn: () => any): any => self.match({ +// Some: (a) => a, +// None: () => fn() +// }) +// +// none_or = (or: (obj: any) => any): Option => { +// return self.match({ +// Some: (some: any) => Option.Some(or(some)), +// None: () => Ray.None +// }) +// } /** * @@ -405,7 +406,7 @@ export class Ray * * Not to be considered as a perfect mapping of JavaScript functionality - merely a practical one. */ -export type JSObj> = { +export type JSObj = { Iterable: (iterable: Iterable) => typeof iterable, Iterator: (iterator: Iterator) => typeof iterator, Boolean: (boolean: boolean) => typeof boolean, @@ -417,10 +418,10 @@ export type JSObj> = { Any: (any: any) => typeof any, None: typeof none; } -export type JSImpl> = { +export type JSImpl = { as_ray: () => Target, } -export type JS> = MemberType, JSImpl>>; +export type JS = MemberType, JSImpl>>; export const JS = enumeration({ Iterable: (iterable: Iterable) => iterable, @@ -432,15 +433,15 @@ export const JS = enumeration({ Any: (any: any) => any, None: none, }, self => class { - as_ray = (): Option => self.match({ - Iterable: (iterable: Iterable): Option => from_iterable(iterable), - Iterator: (iterator: Iterator): Option => from_iterator(iterator), - Boolean: (boolean: boolean): Option => from_boolean(boolean), - // Number: (number: number): Option => from_number(number), - // Function: (func: ParameterlessFunction): Option => from_function(func), - Object: (object: object): Option => from_object(object), - Any: (any: any): Option => Option.Some(new Ray({ js: () => Option.Some(any) })), - None: (): Option => Option.None + as_ray = (): Ray => self.match({ + Iterable: (iterable: Iterable): Ray => from_iterable(iterable), + Iterator: (iterator: Iterator): Ray => from_iterator(iterator), + Boolean: (boolean: boolean): Ray => from_boolean(boolean), + // Number: (number: number): Ray => from_number(number), + // Function: (func: ParameterlessFunction): Ray => from_function(func), + Object: (object: object): Ray => from_object(object), + Any: (any: any): Ray => Option.Some(new Ray({ js: () => Option.Some(any) })), + None: (): Ray => Ray.None }) }); @@ -466,11 +467,11 @@ export const from_any = (any: any): JS => { return JS.Any(any); } -export const from_iterable = (iterable: Iterable): Option => from_iterator(iterable[Symbol.iterator]()); -export const from_iterator = (iterator: Iterator): Option => { +export const from_iterable = (iterable: Iterable): Ray => from_iterator(iterable[Symbol.iterator]()); +export const from_iterator = (iterator: Iterator): Ray => { // [ |--] - const next = (initial: Option): Option => { + const next = (initial: Ray): Ray => { const iterator_result = iterator.next(); const is_terminal = iterator_result.done === true; @@ -481,23 +482,23 @@ export const from_iterator = (iterator: Iterator): Option => { const terminal = new Ray({ initial: () => initial }); - // initial.force().continues_with(() => terminal.as_reference().as_option()); + // initial.force().continues_with(() => terminal.as_reference()); // if (initial.is_some()) // initial.force().terminal = () => terminal; // TODO REPEAT FROM BELOW - return terminal.as_option(); + return terminal; } - const current: Option = Option.Some(new Ray({ + const current: Ray = Option.Some(new Ray({ js: () => Option.Some(iterator_result.value), - // initial: () => new Ray().as_option(), + // initial: () => new Ray(), initial: () => initial, vertex: () => from_any(iterator_result.value).as_ray(), terminal: () => next(current) })); - // initial.force().continues_with(() => current.force().as_reference().as_option()); + // initial.force().continues_with(() => current.force().as_reference()); if (initial.is_some()) initial.force().terminal = () => current; @@ -505,12 +506,12 @@ export const from_iterator = (iterator: Iterator): Option => { } const ray_iterator = new Ray({ js: () => Option.Some(iterator)}); - ray_iterator.terminal = () => next(ray_iterator.as_option()); + ray_iterator.terminal = () => next(ray_iterator); // This indicates we're passing a reference, since traversal logic will be defined at its vertex - what it's defining. - return ray_iterator.as_reference().as_option(); + return ray_iterator.as_reference(); } -export const from_generator = (generator: Generator): Option => { +export const from_generator = (generator: Generator): Ray => { // [ |--] return from_iterable(generator); } @@ -534,19 +535,19 @@ export const js = (value: any): Ray => { return vertex; } -export const length = (of: number, value: any = undefined): Option => { +export const length = (of: number, value: any = undefined): Ray => { let current = empty_vertex().as_reference(); for (let i = 0; i < of; i++) { current = current.continues_with(new Ray({js: () => Option.Some(value)}).as_reference()) } - return current.as_option(); + return current; } // export const at = (index: number, of: number, value: any = undefined): Arbitrary> => { // return Arbitrary.Fn(() => length(of, value).resolve().force().at_terminal(index)); // } // -export const from_boolean = (boolean: boolean): Option => { +export const from_boolean = (boolean: boolean): Ray => { // |-false->-true-| (could of course also be reversed) // from_iterable([false, true]) @@ -557,10 +558,10 @@ export const from_boolean = (boolean: boolean): Option => { // _false.as_reference() // .continues_with(() => - // _true.initial().force().as_reference().as_option() + // _true.initial.force().as_reference() // ); - return (boolean ? _true : _false).as_reference().as_option(); + return (boolean ? _true : _false).as_reference(); } @@ -581,19 +582,19 @@ export const from_boolean = (boolean: boolean): Option => { // export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); -// export const from_number = (number: number): Option => { +// export const from_number = (number: number): Ray => { // // } -// export const from_function = (func: ParameterlessFunction): Option => { +// export const from_function = (func: ParameterlessFunction): Ray => { // // } -export const from_object = (object: object): Option => { +export const from_object = (object: object): Ray => { - return Option.None; + return Ray.None; } // -// export const from_async_generator = (generator: AsyncGenerator): Option => {} -// export const from_generator = (generator: Generator): Option => {} +// export const from_async_generator = (generator: AsyncGenerator): Ray => {} +// export const from_generator = (generator: Generator): Ray => {} export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); export const is_number = (_object: any): _object is number => _.isNumber(_object); diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/implementations/chyp/Chyp.ts index b823f48..96f1859 100644 --- a/src/@orbitmines/external/implementations/chyp/Chyp.ts +++ b/src/@orbitmines/external/implementations/chyp/Chyp.ts @@ -11,6 +11,8 @@ import {Option} from "../../../js/utils/Option"; * NOTE: * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. * + * - The .copy()'s are implemented on Ray. + * * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. * * TODO: Probably want all these types at runtime, to display them @@ -143,7 +145,7 @@ export class VData extends Ray { /** * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. */ - get in_indices(): Ray { throw new NotImplementedError(); } + get in_indices(): Ray { return this.initial } // get out_indices(): Ray { throw new NotImplementedError(); } /** @@ -171,8 +173,8 @@ export class VData extends Ray { merge = (other: VData): Ray => { // TODO: other is destroyed // TODO: Vertices - // this.initial().force().equivalent(other.initial().force()); - // this.terminal().force().equivalent(other.initial().force()); + // this.initial.force().equivalent(other.initial.force()); + // this.terminal.force().equivalent(other.initial.force()); /* @@ -290,16 +292,8 @@ export class Graph extends Ray { get edata(): Ray { throw new NotImplementedError(); } // TODO: Can probably generate these on the fly, or cache them automatically - get vindex(): Ray { throw new NotImplementedError(); } - get eindex(): Ray { throw new NotImplementedError(); } - - __init__ = (): Ray => { - this.vindex = 0; - this.edindex = 0; - } - - // Implemented on Ray - // copy = (): Ray => { throw new NotImplementedError(); } + get vindex(): Ray { return this.vdata.index.max(0); } + get eindex(): Ray { return this.edata.index.max(0); } // TODO .keys vertices = (): Ray => this.vdata; @@ -316,6 +310,7 @@ export class Graph extends Ray { * * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. */ + // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. get domain(): Ray { return this.___domain(this.inputs()) }; /** @@ -325,18 +320,7 @@ export class Graph extends Ray { */ get codomain(): Ray { return this.___domain(this.outputs()) }; - /** - * Return the :class:`VData` associated with vertex id `v`. - * - * @param v Integer identifier of the vertex. - */ vertex_data = (v = int): VData => this.vertices().at(v).cast(); - - /** - * Return the :class:`EData` associated with edge id `e`. - * - * @param e Integer identifier of the edge. - */ edge_data = (e = int): EData => this.edges().at(e).cast(); // TODO: Shouldnt be here @@ -665,9 +649,62 @@ export class Graph extends Ray { * if len(plug1) != len(plug2): * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' * + f'outputs into one with {len(plug2)} inputs') + * + * self.set_outputs([vmap[v] for v in other.outputs()]) */ + // [outputs to inputs] + // Go through pairs of vertices from each plug + compose.zip().all(([input, output]) => { + /** + * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. + */ + + // TODO: does this ever happen??? + // while p1 in quotient: + // p1 = quotient[p1] + // while p2 in quotient: + // p2 = quotient[p2] + + + // TODO, Again the same equivalence check for loops etc.. + { + // If the resulting p1 and p2 are not the same vertex, merge them. + if (input === output) + return; + + // TODO; DO this on the vertices; + // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) + + // If both vertices have flexible types that are not equal, raise an error due to ambiguity. + // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. + + + // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. + ['vtype', 'size'].forEach(structure => { + const infer = `infer_${structure}`; + + if (input[infer] && output[infer] && input[structure] !== output[structure]) { + throw GraphError(`Ambiguous vertex ${structure} during composition.`) + + } else if (input[infer]) { + // Otherwise, if one vertex has a flexible type, ensure the vertex types match. + // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it + // TODO: Again both sides same thing.. + input[structure] = output[structure]; // TODO: Generalized structure + input[infer] = false; + } else if (output.infer_type) { + output[structure] = input[structure]; + output[infer] = false; + } + }); + + input.merge(output); + // # Register than p2 has been merged into p1. + // quotient[p2] = p1 + } + }); } /** @@ -710,6 +747,8 @@ export class Graph extends Ray { this.edata .filter(edge => edges.includes(edge)) .all(edge => edge.cast().highlight = bool(true)); + + } /** @@ -719,10 +758,8 @@ export class Graph extends Ray { */ unhighlight = (): Ray => { // TODO: These could be merged - this.vdata - .all(vertex => vertex.cast().highlight = bool(false)); - this.edata - .all(edge => edge.cast().highlight = bool(false)); + this.vdata.highlight = false; + this.edata.highlight = false; } } diff --git a/src/@orbitmines/js/utils/Option.ts b/src/@orbitmines/js/utils/Option.ts deleted file mode 100644 index d13d10c..0000000 --- a/src/@orbitmines/js/utils/Option.ts +++ /dev/null @@ -1,52 +0,0 @@ -import {enumeration, MemberType, none, TaggedUnion} from "./match"; - -/** - * Rust-like Option - * - * <3 https://github.com/suchipi/safety-match/issues/15#issuecomment-1384721329 - */ -export type OptionObj = { - Some: (some: T) => T; - None: typeof none; -} -export type OptionImpl = { - force: () => T, - none_or: (or: (obj: T) => Result) => Option, - default: (fn: () => T) => T, - is_some: () => boolean, - is_none: () => boolean, -} -export type Option = MemberType, OptionImpl>>; - -export const Option = enumeration, OptionImpl>({ - Some: (some: any) => some, - None: none, -}, self => class { - force = (): any => self.match({ - Some: (a) => a, - None: () => { throw new Error('Expected Some(value) to be present but found None.') } - }); - - default = (fn: () => any): any => self.match({ - Some: (a) => a, - None: () => fn() - }) - - none_or = (or: (obj: any) => any): Option => { - return self.match({ - Some: (some: any) => Option.Some(or(some)), - None: () => Option.None - }) - } - - is_some = (): boolean => self.match({ - Some: (_) => true, - None: () => false - }) - - is_none = (): boolean => self.match({ - Some: (_) => false, - None: () => true - }) - -}); \ No newline at end of file diff --git a/src/@orbitmines/js/utils/match.ts b/src/@orbitmines/js/utils/match.ts deleted file mode 100644 index 11ed9e0..0000000 --- a/src/@orbitmines/js/utils/match.ts +++ /dev/null @@ -1,142 +0,0 @@ -// Rust-like enum pattern matching: <3 https://github.com/suchipi/safety-match -// ~ also added some additional functionality to define functions at the union level. - -import _ from "lodash"; - -export const none = Symbol(); - -export type None = typeof none; - -const MEMBER_TYPE = Symbol(); - -export type MemberType< - TaggedUnionT extends { - [MEMBER_TYPE]: any; - } -> = TaggedUnionT[typeof MEMBER_TYPE]; - -type DefObjSuper = { [key: string]: None | ((...args: any[]) => any) }; - -type DataMap = { - [Property in keyof DefObj]: DefObj[Property] extends (...args: any) => any - ? ReturnType - : DefObj[Property] extends None - ? undefined - : DefObj[Property]; -}; - -export type CasesObjFull = { - [Property in keyof DataMap]: DataMap[Property] extends None - ? () => any - : (data: DataMap[Property]) => any; -}; - -// Would call this CasesObjPartial if we didn't need to use the name for error reporting -type if_you_are_seeing_this_then_your_match_didnt_either_handle_all_cases_or_provide_a_default_handler_using_underscore< - DefObj extends DefObjSuper -> = Partial> & { - _: >( - data: DataMap[Property] - ) => any; -}; - -export type MatchConfiguration = - | CasesObjFull - | if_you_are_seeing_this_then_your_match_didnt_either_handle_all_cases_or_provide_a_default_handler_using_underscore; - -type MemberObject< - DefObj extends DefObjSuper, - DefImpl -> = MemberImpl & { - match>( - casesObj: C - ): ReturnType>; - variant: keyof DefObj; - data: DataMap[keyof DefObj]; -}; - -export type TaggedUnion = { - [Property in keyof DefObj]: DefObj[Property] extends (...args: any) => any - ? (...args: Parameters) => MemberObject - : MemberObject; -} & { - [MEMBER_TYPE]: MemberObject; -}; - -export type MemberImpl = { - [Property in keyof DefImpl]: DefImpl[Property] extends (...args: infer TArgs) => infer TResult - ? (...args: TArgs) => TResult - : never; -} - - -const MemberObjectImpl = class MemberObjectImpl { - variant: any; - data: any; - - constructor(variant: any, data: any) { - this.variant = variant; - this.data = data; - } - - match(casesObj: any): any { - const data = this.data; - const matchingHandler = casesObj[this.variant]; - - if (matchingHandler) { - return matchingHandler(data); - } else if (casesObj._) { - return casesObj._(data); - } else { - throw new Error(`Match did not handle variant: '${this.variant}'`); - } - } -} -Object.defineProperty(MemberObjectImpl, "name", { value: "MemberObject" }); - - -export const enumeration = < - DefObj extends DefObjSuper, - DefImpl extends object ->( - mapping: DefObj, - constructor?: (self: MemberObject) => (new () => DefImpl), -): TaggedUnion => { - - const createImpl = (variant: keyof DefObj, data: any) => { - const impl = new MemberObjectImpl(variant, data) as any; - if (constructor === undefined) - return impl; - - const defImpl = new (constructor(impl))(); - - Object.keys(defImpl).forEach((methodName) => { - // @ts-ignore - const method: ((...args: any[]) => any) = defImpl[methodName]; - - Object.defineProperty(impl, methodName, { - value: (...args: any[]) => method(...args) - }) - }); - - return impl; - } - - - const enumeration: any = {}; - - Object.keys(mapping).forEach((key) => { - const value = mapping[key]; - - if (_.isFunction(value)) { - enumeration[key] = (...args: any) => { - const data = value(...args); - return createImpl(key, data); - }; - } else { - enumeration[key] = createImpl(key, undefined); - } - }); - - return enumeration; -} From 77f5ba76591e66b1ddbe632df9064d31be6a3049 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 8 Jan 2024 21:44:41 +0100 Subject: [PATCH 020/138] 2024/02/08 - Moving around some Ray definitions --- src/@orbitmines/explorer/Ray.ts | 343 +++++++++++++------------------- 1 file changed, 135 insertions(+), 208 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index e2d4af3..d7cfcdd 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,7 +1,7 @@ -import {enumeration, MemberType, none, TaggedUnion} from "../../@orbitmines/js/utils/match"; import _ from "lodash"; import {NotImplementedError} from "./errors/errors"; + // SHOULDNT CLASSIFY THESE? export enum RayType { REFERENCE = ' | ', @@ -49,8 +49,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? PossiblyHomoiconic, AsyncIterable, - Iterable - // TODO: Array, Dictionary... + Iterable, + Array + // Dict { js: Arbitrary @@ -115,19 +116,39 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ is_none = (): boolean => this.self === this; - static None = (): Ray => { - const self = new Ray({}); + /** [ ] */ static None = (): Ray => { + const self = Ray.empty(); // TODO: None, could also self-reference the ray on which it's defining to be None. Now it's just an ignorant loop. self.self = () => self; return self; } is_some = (): boolean => !this.is_none(); + /** [ ] */ static empty = () => new Ray({ }); + /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { + /** [ ] */ const vertex = Ray.empty(); + /** [-- ] */ vertex.initial = vertex.as_initial; + /** [ ? ] */ vertex.vertex = value; + /** [ --] */ vertex.terminal = vertex.as_terminal; + + /** [--?--] */ return vertex; + } + static js = (value: any) => { const vertex = Ray.vertex(); vertex.js = () => value; return vertex; } + + static size = (of: number, value: any = undefined): Ray => { + let current = Ray.vertex().as_reference(); // TODO; This sort of thing should be lazy + for (let i = 0; i < of; i++) { + current = current.continues_with(Ray.js(value).as_reference()); + } + + return current; + } + /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ - /** [ | ] -> [?????] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); - /** [ | ] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }).as_reference(); - /** [ | ] -> [??? ] */ as_terminal = () => - new Ray({ initial: this.as_arbitrary(), vertex: () => this.terminal, js: () => 'terminal ref' }).as_reference(); // TODO: These fields as DEBUG + /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); + /** [?????] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }); + /** [?????] -> [??? ] */ as_terminal = () => + new Ray({ initial: this.as_arbitrary(), vertex: () => this.terminal, js: () => 'terminal ref' }); // TODO: These fields as DEBUG // as_option = (): Ray => Option.Some(this); as_arbitrary = (): Arbitrary => () => this; @@ -143,13 +164,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? throw 'NotImplemented: Preventing implementation bug; continues_with not called as a reference'; // TODO: For now just puts it at the vertex, could be done more intelligently - const next_vertex = new Ray({ - initial: empty().as_arbitrary(), - vertex: () => continues_with.vertex, - terminal: empty().as_arbitrary() - }); + const next_vertex = Ray.vertex(() => continues_with.vertex); - const vertex = this.self.force(); + const vertex = this.self; if (vertex.is_empty()) { console.log('first element') @@ -160,26 +177,16 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (!this.is_vertex()) throw 'NotImplemented: Preventing implementation bug; continues_with not called on a vertex'; - const terminal = vertex.terminal.force(); - if (!terminal.is_empty()) + if (!vertex.terminal.is_empty()) throw 'NotImplemented: Preventing implementation bug; continues_with should be added to the vertex'; // [ |--] - const next_connection = new Ray({ - initial: vertex.as_arbitrary(), - vertex: terminal.as_arbitrary(), - js: () => Option.Some('terminal ref') - }); + const next_connection = vertex.as_terminal(); // console.log(initial_connection.label) vertex.terminal = next_connection.as_arbitrary(); - const initial = next_vertex.initial; - const previous_connection = new Ray({ - vertex: () => initial, - terminal: next_vertex.as_arbitrary(), - js: () => Option.Some('initial ref') - }); + const previous_connection = next_vertex.as_initial(); next_vertex.initial = previous_connection.as_arbitrary(); @@ -210,7 +217,21 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO; Could return the ignorant reference to both instances, or just the result., .. copy = (): Ray => { throw new NotImplementedError() } - at = (steps: Ray | Arbitrary): Ray => { throw new NotImplementedError(); } + + // export const at = (index: number, of: number, value: any = undefined): Arbitrary> => { +// return Arbitrary.Fn(() => length(of, value).resolve().force().at_terminal(index)); +// } +// + at = (steps: number | Ray | Arbitrary): Ray => { throw new NotImplementedError(); } + // +// export const permutation = (permutation: number | undefined, of: number): Arbitrary> => at( +// // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) +// permutation ?? 0, +// // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. +// permutation === undefined ? 1 : of +// ) +// + // export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); /** * Cast to some JavaScript object @@ -293,13 +314,12 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (c[this.label] !== undefined) return c[this.label]!; - const of = (option: Ray): string => option.match({ - Some: (ray) => { - ray.debug(c) ; - return ray.label; - }, - None: () => 'None' - }); + const of = (ray: Ray): string => { + if (ray.is_none()) return 'None'; + + ray.debug(c); + return ray.label; + } const obj: any = { label: this.label }; c[this.label] = obj; @@ -379,7 +399,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (this.__label !== undefined) return this.__label; - return this.__label = `"${Ray._label++} (${this.js().match({ Some: (js) => js.toString(), None: () => '?' })})"`; + return this.__label = `"${Ray._label++} (${this.js()?.toString() ?? '?'})})"`; } } @@ -406,203 +426,110 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * Not to be considered as a perfect mapping of JavaScript functionality - merely a practical one. */ -export type JSObj = { - Iterable: (iterable: Iterable) => typeof iterable, - Iterator: (iterator: Iterator) => typeof iterator, - Boolean: (boolean: boolean) => typeof boolean, - // // AsyncGenerator - // // .. + // Number: (number: number) => typeof number, // Function: (func: ParameterlessFunction) => typeof func, - Object: (object: object) => typeof object, - Any: (any: any) => typeof any, - None: typeof none; -} -export type JSImpl = { - as_ray: () => Target, -} -export type JS = MemberType, JSImpl>>; -export const JS = enumeration({ - Iterable: (iterable: Iterable) => iterable, - Iterator: (iterator: Iterator) => iterator, - Boolean: (boolean: boolean) => boolean, // Number: (number: number) => number, // Function: (func: ParameterlessFunction) => func, - Object: (object: object) => object, - Any: (any: any) => any, - None: none, -}, self => class { - as_ray = (): Ray => self.match({ - Iterable: (iterable: Iterable): Ray => from_iterable(iterable), - Iterator: (iterator: Iterator): Ray => from_iterator(iterator), - Boolean: (boolean: boolean): Ray => from_boolean(boolean), - // Number: (number: number): Ray => from_number(number), - // Function: (func: ParameterlessFunction): Ray => from_function(func), - Object: (object: object): Ray => from_object(object), - Any: (any: any): Ray => Option.Some(new Ray({ js: () => Option.Some(any) })), - None: (): Ray => Ray.None - }) -}); -/** - * - */ -export const from_any = (any: any): JS => { - if (any === null || any === undefined) - return JS.Any(any); +export namespace JS { + export const Boolean = (boolean: boolean): Ray => { + // |-false->-true-| (could of course also be reversed) + const _false = Ray.js(false); + const _true = Ray.js(true); + _false.continues_with(_true); - if (is_boolean(any)) - return JS.Boolean(any); - // if (is_number(any)) - // return JS.Number(any); - if (is_iterable(any))// || is_array(any)) - return JS.Iterable(any); - // if (is_function(any)) - // return JS.Function(any); - if (is_object(any)) - return JS.Object(any); - - return JS.Any(any); -} - -export const from_iterable = (iterable: Iterable): Ray => from_iterator(iterable[Symbol.iterator]()); -export const from_iterator = (iterator: Iterator): Ray => { - // [ |--] - - const next = (initial: Ray): Ray => { - const iterator_result = iterator.next(); - const is_terminal = iterator_result.done === true; - - if (is_terminal) { - // We're done, this is the end of the iterator - - // vertex: could have something at the vertex which defines the "end of the iterator" - but we don't here. - const terminal = new Ray({ - initial: () => initial - }); - // initial.force().continues_with(() => terminal.as_reference()); - - // if (initial.is_some()) - // initial.force().terminal = () => terminal; // TODO REPEAT FROM BELOW + return (boolean ? _true : _false).as_reference(); + } + // export const bit = (bit?: boolean): Arbitrary> => permutation(bit ? 1 : 0, 2); + export const Bit = Boolean; - return terminal; - } + export const Iterable = (iterable: Iterable): Ray => JS.Iterator(iterable[Symbol.iterator]()); - const current: Ray = Option.Some(new Ray({ - js: () => Option.Some(iterator_result.value), - // initial: () => new Ray(), - initial: () => initial, - vertex: () => from_any(iterator_result.value).as_ray(), - terminal: () => next(current) - })); + export const Iterator = (iterator: Iterator): Ray => { + // [ |--] - // initial.force().continues_with(() => current.force().as_reference()); - if (initial.is_some()) - initial.force().terminal = () => current; + const next = (initial: Ray): Ray => { + const iterator_result = iterator.next(); + const is_terminal = iterator_result.done === true; - return current; - } + if (is_terminal) { + // We're done, this is the end of the iterator - const ray_iterator = new Ray({ js: () => Option.Some(iterator)}); - ray_iterator.terminal = () => next(ray_iterator); + // vertex: could have something at the vertex which defines the "end of the iterator" - but we don't here. + const terminal = new Ray({ + initial: () => initial + }); + // initial.force().continues_with(() => terminal.as_reference()); - // This indicates we're passing a reference, since traversal logic will be defined at its vertex - what it's defining. - return ray_iterator.as_reference(); -} -export const from_generator = (generator: Generator): Ray => { - // [ |--] - return from_iterable(generator); -} + // if (initial.is_some()) + // initial.force().terminal = () => terminal; // TODO REPEAT FROM BELOW -export const empty = (): Ray => new Ray({ }); -export const empty_vertex = (): Ray => { - const initial = empty(); - const terminal = empty(); - const vertex = new Ray({ initial: initial.as_arbitrary(), terminal: terminal.as_arbitrary() }); + return terminal; + } - initial.terminal = vertex.as_arbitrary(); - terminal.initial = vertex.as_arbitrary(); + const current: Ray = new Ray({ + js: () => iterator_result.value, + // initial: () => new Ray(), + initial: () => initial, + vertex: () => from_any(iterator_result.value).as_ray(), + terminal: () => next(current) + }); - return vertex; -} + // initial.force().continues_with(() => current.force().as_reference()); + if (initial.is_some()) + initial.terminal = () => current; -export const js = (value: any): Ray => { - const vertex = empty_vertex(); - vertex.js = () => Option.Some(value); + return current; + } - return vertex; -} + const ray_iterator = new Ray({ js: () => Option.Some(iterator)}); + ray_iterator.terminal = () => next(ray_iterator); -export const length = (of: number, value: any = undefined): Ray => { - let current = empty_vertex().as_reference(); - for (let i = 0; i < of; i++) { - current = current.continues_with(new Ray({js: () => Option.Some(value)}).as_reference()) + // This indicates we're passing a reference, since traversal logic will be defined at its vertex - what it's defining. + return ray_iterator.as_reference(); } - return current; -} -// export const at = (index: number, of: number, value: any = undefined): Arbitrary> => { -// return Arbitrary.Fn(() => length(of, value).resolve().force().at_terminal(index)); -// } -// -export const from_boolean = (boolean: boolean): Ray => { - // |-false->-true-| (could of course also be reversed) - - // from_iterable([false, true]) + export const Generator = (generator: Generator): Ray => JS.Iterable(generator); - const _false = js(false); - const _true = js(true); - // const two = _false.continues_with(_true); + // export const AsyncGenerator = (generator: AsyncGenerator): Ray => { + // // [ |--] + // return JS.Iterable(generator); + // } - // _false.as_reference() - // .continues_with(() => - // _true.initial.force().as_reference() - // ); - - return (boolean ? _true : _false).as_reference(); -} + export const Number = (number: number): Ray => { + throw new NotImplementedError(); + } + export const Function = (func: Arbitrary): Ray => { + throw new NotImplementedError(); + } -// // Full permutation -// export const SuperPosition = (ray: Ray) => { -// -// } -// -// -// export const permutation = (permutation: number | undefined, of: number): Arbitrary> => at( -// // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) -// permutation ?? 0, -// // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. -// permutation === undefined ? 1 : of -// ) -// -// export const bit = (bit?: boolean): Arbitrary> => permutation(bit ? 1 : 0, 2); -// export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); + export const Object = (object: object): Ray => { + throw new NotImplementedError(); + } + export const Any = (any: any): Ray => { + if (any === null || any === undefined) return JS.Any(any); + if (JS.is_boolean(any)) return JS.Boolean(any); + if (JS.is_number(any)) return JS.Number(any); + if (JS.is_iterable(any)) return JS.Iterable(any); // || is_array(any)) + if (JS.is_function(any)) return JS.Function(any); + if (JS.is_object(any)) return JS.Object(any); -// export const from_number = (number: number): Ray => { -// -// } -// export const from_function = (func: ParameterlessFunction): Ray => { -// -// } -export const from_object = (object: object): Ray => { + return JS.Any(any); + } - return Ray.None; -} -// -// export const from_async_generator = (generator: AsyncGenerator): Ray => {} -// export const from_generator = (generator: Generator): Ray => {} - -export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); -export const is_number = (_object: any): _object is number => _.isNumber(_object); -export const is_object = (_object: any): _object is object => _.isObject(_object); -export const is_iterable = (_object: any): _object is Iterable => Symbol.iterator in Object(_object); -export const is_async_iterable = (_object: any): _object is AsyncIterable => Symbol.asyncIterator in Object(_object); -export const is_array = (_object: any): _object is T[] => _.isArray(_object); -export const is_async = (_object: any) => _.has(_object, 'then') && is_function(_.get(_object, 'then')); // TODO, Just an ugly check - -export const is_error = (_object: any): _object is Error => _.isError(_object); -export const is_function = (_object: any): _object is ((...args: any[]) => any) => _.isFunction(_object); + export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); + export const is_number = (_object: any): _object is number => _.isNumber(_object); + export const is_object = (_object: any): _object is object => _.isObject(_object); + export const is_iterable = (_object: any): _object is Iterable => Symbol.iterator in Object(_object); + export const is_async_iterable = (_object: any): _object is AsyncIterable => Symbol.asyncIterator in Object(_object); + export const is_array = (_object: any): _object is T[] => _.isArray(_object); + export const is_async = (_object: any) => _.has(_object, 'then') && is_function(_.get(_object, 'then')); // TODO, Just an ugly check + + export const is_error = (_object: any): _object is Error => _.isError(_object); + export const is_function = (_object: any): _object is ((...args: any[]) => any) => _.isFunction(_object); +} \ No newline at end of file From 0eecb631ff7d74738af3d8c6427d4ce1e7eb1296 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 12:56:18 +0100 Subject: [PATCH 021/138] 2024/02/09 - Setting up test, fixing self-referential bugs --- .gitmodules | 4 +- package-lock.json | 22076 +++++++++------- package.json | 8 + src/@orbitmines/explorer/Ray.spec.ts | 142 + src/@orbitmines/explorer/Ray.ts | 27 +- src/@orbitmines/explorer/errors/errors.ts | 1 + .../{implementations => }/chyp/Chyp.ts | 0 .../{implementations => }/chyp/ChypCanvas.tsx | 0 .../external/github.com/akissinger/chyp | 1 - 9 files changed, 13315 insertions(+), 8944 deletions(-) create mode 100644 src/@orbitmines/explorer/Ray.spec.ts rename src/@orbitmines/external/{implementations => }/chyp/Chyp.ts (100%) rename src/@orbitmines/external/{implementations => }/chyp/ChypCanvas.tsx (100%) delete mode 160000 src/@orbitmines/external/github.com/akissinger/chyp diff --git a/.gitmodules b/.gitmodules index df36d3d..d94fdb8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "src/@orbitmines/external/github.com/akissinger/chyp"] - path = src/@orbitmines/external/github.com/akissinger/chyp +[submodule "external/github.com/akissinger/chyp"] + path = external/github.com/akissinger/chyp url = git@github.com:akissinger/chyp.git diff --git a/package-lock.json b/package-lock.json index 72bd891..b3fa804 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,12 +36,14 @@ }, "devDependencies": { "@react-pdf/types": "^2.3.1", + "@types/jest": "^29.5.11", "@types/lodash": "^4.14.194", "@types/node": "^20.1.0", "@types/prismjs": "^1.26.0", "@types/react": "^18.2.6", "@types/react-dom": "^18.2.4", "@types/react-helmet": "^6.1.7", + "jest": "^29.7.0", "node-polyfill-webpack-plugin": "^2.0.1", "react-app-rewired": "^2.2.1", "react-dev-utils": "^12.0.1", @@ -50,6 +52,8 @@ "tree-sitter": "^0.20.6", "tree-sitter-python": "^0.20.4", "tree-sitter-typescript": "^0.20.3", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.2", "typescript": "^5.0.4" } }, @@ -2313,6 +2317,28 @@ } } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@csstools/normalize.css": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", @@ -2802,57 +2828,120 @@ } }, "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, "dependencies": { - "@jest/types": "^27.5.1", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@jest/console/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/console/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "emittery": "^0.8.1", + "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", - "rimraf": "^3.0.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -2863,1129 +2952,1197 @@ } } }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "node_modules/@jest/core/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "node_modules/@jest/core/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "node_modules/@jest/core/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "node_modules/@jest/core/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@jest/core/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "node_modules/@jest/core/node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "node_modules/@jest/core/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "callsites": "^3.0.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" + "picomatch": "^2.2.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@jest/core/node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "node_modules/@jest/core/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@jest/core/node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/@jest/transform/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "node_modules/@jest/core/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "node_modules/@jest/environment/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^16.0.0", + "@types/yargs": "^17.0.8", "chalk": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "node_modules/@jest/environment/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@jest/environment/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" }, "engines": { - "node": ">=6.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, "engines": { - "node": ">=6.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "node_modules/@jest/expect-utils/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, "engines": { - "node": ">=6.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "node_modules/@jest/fake-timers/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@juggle/resize-observer": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", - "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@mediapipe/tasks-vision": { - "version": "0.10.8", - "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.8.tgz", - "integrity": "sha512-Rp7ll8BHrKB3wXaRFKhrltwZl1CiXGdibPxuWXvqGnKTnv8fqa/nvftYNuSbf+pbJWKYCXdBtYTITdAUTGGh0Q==" + "node_modules/@jest/fake-timers/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "node_modules/@jest/fake-timers/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "eslint-scope": "5.1.1" + "@types/yargs-parser": "*" } }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/@jest/fake-timers/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, "engines": { - "node": ">=4.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@jest/globals/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@jest/globals/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@jest/globals/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@jest/globals/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" + "@types/yargs-parser": "*" } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz", - "integrity": "sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==", + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, "dependencies": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.23.3", - "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.4", - "schema-utils": "^3.0.0", - "source-map": "^0.7.3" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": ">= 10.13" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "@types/webpack": "4.x || 5.x", - "react-refresh": ">=0.10.0 <1.0.0", - "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <5.0.0", - "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x", - "webpack-hot-middleware": "2.x", - "webpack-plugin-serve": "0.x || 1.x" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { - "@types/webpack": { - "optional": true - }, - "sockjs-client": { - "optional": true - }, - "type-fest": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - }, - "webpack-hot-middleware": { - "optional": true - }, - "webpack-plugin-serve": { + "node-notifier": { "optional": true } } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "node_modules/@jest/reporters/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": ">=8.9.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "node_modules/@jest/reporters/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" }, "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-pdf/fns": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@react-pdf/fns/-/fns-2.0.1.tgz", - "integrity": "sha512-/vgecczzFYBQFkgUupH+sxXhLWQtBwdwCgweyh25XOlR4NZuaMD/UVUDl4loFHhRQqDMQq37lkTcchh7zzW6ug==", + "node_modules/@jest/reporters/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.20.13" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-pdf/font": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/@react-pdf/font/-/font-2.3.7.tgz", - "integrity": "sha512-NoCieWea6c1mCpDBoyjPbUEC1qXa+S/M7+8vYPZ71aTMgX7co3gQc2e6YKwrSQeQP+BsBq3LSVhjI2ETXfcytw==", + "node_modules/@jest/reporters/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.20.13", - "@react-pdf/types": "^2.3.4", - "cross-fetch": "^3.1.5", - "fontkit": "^2.0.2", - "is-url": "^1.2.4" + "@types/yargs-parser": "*" } }, - "node_modules/@react-pdf/image": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@react-pdf/image/-/image-2.2.2.tgz", - "integrity": "sha512-990JvRZuhsnHyAGd7gvmhfr+4/5PAHLH9IgDstaEDLEq2eFAIQFuNM7k3D6kjKgV1mM7Jqif3CWqrcHBF3jrJw==", + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.20.13", - "@react-pdf/png-js": "^2.2.0", - "cross-fetch": "^3.1.5" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@react-pdf/layout": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/@react-pdf/layout/-/layout-3.6.3.tgz", - "integrity": "sha512-w6ACZ9o18Q5wbzsY9a4KW2Gqn6Drt3AN/kb/I6SBz/L7PAJ9rPQBIDq/s5qZJ+/WwWy33rcC8WC1givtDhjCHQ==", + "node_modules/@jest/reporters/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.20.13", - "@react-pdf/fns": "2.0.1", - "@react-pdf/image": "^2.2.2", - "@react-pdf/pdfkit": "^3.0.2", - "@react-pdf/primitives": "^3.0.0", - "@react-pdf/stylesheet": "^4.1.8", - "@react-pdf/textkit": "^4.2.0", - "@react-pdf/types": "^2.3.4", - "@react-pdf/yoga": "^4.1.2", - "cross-fetch": "^3.1.5", - "emoji-regex": "^10.2.1", - "queue": "^6.0.1" + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/@react-pdf/pdfkit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@react-pdf/pdfkit/-/pdfkit-3.0.2.tgz", - "integrity": "sha512-+m5rwNCwyEH6lmnZWpsQJvdqb6YaCCR0nMWrc/KKDwznuPMrGmGWyNxqCja+bQPORcHZyl6Cd/iFL0glyB3QGw==", - "dependencies": { - "@babel/runtime": "^7.20.13", - "@react-pdf/png-js": "^2.2.0", - "browserify-zlib": "^0.2.0", - "crypto-js": "^4.0.0", - "fontkit": "^2.0.2", - "vite-compatible-readable-stream": "^3.6.1" + "node_modules/@jest/reporters/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-pdf/png-js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@react-pdf/png-js/-/png-js-2.2.0.tgz", - "integrity": "sha512-csZU5lfNW73tq7s7zB/1rWXGro+Z9cQhxtsXwxS418TSszHUiM6PwddouiKJxdGhbVLjRIcuuFVa0aR5cDOC6w==", + "node_modules/@jest/reporters/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "browserify-zlib": "^0.2.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-pdf/primitives": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@react-pdf/primitives/-/primitives-3.0.1.tgz", - "integrity": "sha512-0HGcknrLNwyhxe+SZCBL29JY4M85mXKdvTZE9uhjNbADGgTc8wVnkc5+e4S/lDvugbVISXyuIhZnYwtK9eDnyQ==" - }, - "node_modules/@react-pdf/render": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@react-pdf/render/-/render-3.2.7.tgz", - "integrity": "sha512-fAgbbAAkVL0hpcf1vUJLHxuPjPBqZuq8nors7fCwvoatBBwOWP9fza7IDPeFKN7+ZOnfmIZzes8Kc/DNHzJohw==", + "node_modules/@jest/reporters/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.20.13", - "@react-pdf/fns": "2.0.1", - "@react-pdf/primitives": "^3.0.0", - "@react-pdf/textkit": "^4.2.0", - "@react-pdf/types": "^2.3.4", - "abs-svg-path": "^0.1.1", - "color-string": "^1.5.3", - "normalize-svg-path": "^1.1.0", - "parse-svg-path": "^0.1.2", - "svg-arc-to-cubic-bezier": "^3.2.0" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-pdf/renderer": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/@react-pdf/renderer/-/renderer-3.1.14.tgz", - "integrity": "sha512-Qk29uTamH6q+drK/YmiFbuQQ+yutesfIe+wyrsXFoUJUutIiDIaibO6zByMkhWb3M6CMt6NvG3NLHio1OF8U6Q==", + "node_modules/@jest/reporters/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.20.13", - "@react-pdf/font": "^2.3.7", - "@react-pdf/layout": "^3.6.3", - "@react-pdf/pdfkit": "^3.0.2", - "@react-pdf/primitives": "^3.0.0", - "@react-pdf/render": "^3.2.7", - "@react-pdf/types": "^2.3.4", - "events": "^3.3.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "queue": "^6.0.1", - "scheduler": "^0.17.0" + "yallist": "^4.0.0" }, - "peerDependencies": { - "react": "^16.8.6 || ^17.0.0 || ^18.0.0" + "engines": { + "node": ">=10" } }, - "node_modules/@react-pdf/stylesheet": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@react-pdf/stylesheet/-/stylesheet-4.1.8.tgz", - "integrity": "sha512-/EuB9RBsH3YYRj8mwzImaul619MvX3rsHNF4h8LnlwDOuBehPA3L/fHrikfPqtJvHqK2ty3GXnkw0HG5SQpMzw==", + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.20.13", - "@react-pdf/fns": "2.0.1", - "@react-pdf/types": "^2.3.4", - "color-string": "^1.5.3", - "hsl-to-hex": "^1.0.0", - "media-engine": "^1.0.3", - "postcss-value-parser": "^4.1.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@react-pdf/textkit": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@react-pdf/textkit/-/textkit-4.2.0.tgz", - "integrity": "sha512-R90pEOW6NdhUx4p99iROvKmwB06IRYdXMhh0QcmUeoPOLe64ZdMfs3LZliNUWgI5fCmq71J+nv868i/EakFPDg==", + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.20.13", - "@react-pdf/fns": "2.0.1", - "hyphen": "^1.6.4", - "unicode-properties": "^1.4.1" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/@react-pdf/types": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@react-pdf/types/-/types-2.3.4.tgz", - "integrity": "sha512-vGGz21BTE05EktBbotbd7fjC0Yi8A/lOSIpzd7L7aF1XY+vyIHlQVb35DWCipM1p/6XN4cr9etGAmm1e4Mtmjw==" - }, - "node_modules/@react-pdf/yoga": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@react-pdf/yoga/-/yoga-4.1.2.tgz", - "integrity": "sha512-OlMZkFrJDj4GyKZ70thiObwwPVZ52B7mlPyfzwa+sgwsioqHXg9nMWOO+7SQFNUbbOGagMUu0bCuTv+iXYZuaQ==", + "node_modules/@jest/reporters/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.20.13" + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/@react-spring/animated": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.6.1.tgz", - "integrity": "sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ==", + "node_modules/@jest/reporters/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", "dependencies": { - "@react-spring/shared": "~9.6.1", - "@react-spring/types": "~9.6.1" + "@sinclair/typebox": "^0.24.1" }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@react-spring/core": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.6.1.tgz", - "integrity": "sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ==", + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, "dependencies": { - "@react-spring/animated": "~9.6.1", - "@react-spring/rafz": "~9.6.1", - "@react-spring/shared": "~9.6.1", - "@react-spring/types": "~9.6.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-spring/donate" + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-spring/rafz": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.6.1.tgz", - "integrity": "sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ==" + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@react-spring/shared": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.6.1.tgz", - "integrity": "sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw==", + "node_modules/@jest/test-result/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "@react-spring/rafz": "~9.6.1", - "@react-spring/types": "~9.6.1" + "@sinclair/typebox": "^0.27.8" }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-spring/three": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.6.1.tgz", - "integrity": "sha512-Tyw2YhZPKJAX3t2FcqvpLRb71CyTe1GvT3V+i+xJzfALgpk10uPGdGaQQ5Xrzmok1340DAeg2pR/MCfaW7b8AA==", + "node_modules/@jest/test-result/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "@react-spring/animated": "~9.6.1", - "@react-spring/core": "~9.6.1", - "@react-spring/shared": "~9.6.1", - "@react-spring/types": "~9.6.1" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, - "peerDependencies": { - "@react-three/fiber": ">=6.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "three": ">=0.126" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-spring/types": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.6.1.tgz", - "integrity": "sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==" + "node_modules/@jest/test-result/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/@react-three/drei": { - "version": "9.88.16", - "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.88.16.tgz", - "integrity": "sha512-AcDTRVmXL81KYQvEz7XSxUqj0W5s8c5XgtYzAx+ttB86tEAxp3r7DXc6ZZdMAUZyfw5BSPHx9hKMHr4xmoFdPg==", + "node_modules/@jest/test-result/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.11.2", - "@mediapipe/tasks-vision": "0.10.8", - "@react-spring/three": "~9.6.1", - "@use-gesture/react": "^10.2.24", - "camera-controls": "^2.4.2", - "cross-env": "^7.0.3", - "detect-gpu": "^5.0.28", - "glsl-noise": "^0.0.0", - "lodash.clamp": "^4.0.3", - "lodash.omit": "^4.5.0", - "lodash.pick": "^4.4.0", - "maath": "^0.9.0", - "meshline": "^3.1.6", - "react-composer": "^5.0.3", - "react-merge-refs": "^1.1.0", - "stats-gl": "^1.0.4", - "stats.js": "^0.17.0", - "suspend-react": "^0.1.3", - "three-mesh-bvh": "^0.6.7", - "three-stdlib": "^2.28.0", - "troika-three-text": "^0.47.2", - "utility-types": "^3.10.0", - "uuid": "^9.0.1", - "zustand": "^3.5.13" - }, - "peerDependencies": { - "@react-three/fiber": ">=8.0", - "react": ">=18.0", - "react-dom": ">=18.0", - "three": ">=0.137" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - } + "@types/yargs-parser": "*" } }, - "node_modules/@react-three/fiber": { - "version": "8.15.11", - "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.15.11.tgz", - "integrity": "sha512-jOJjrjVMBJQwIK6Uirc3bErUCTiclbS2alJG1eU8pV1jIwDZwPwcfHzSi2TautxoA4ddMt5DmlpatK4rIqM4jA==", + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.17.8", - "@types/react-reconciler": "^0.26.7", - "@types/webxr": "*", - "base64-js": "^1.5.1", - "buffer": "^6.0.3", - "its-fine": "^1.0.6", - "react-reconciler": "^0.27.0", - "react-use-measure": "^2.1.1", - "scheduler": "^0.21.0", - "suspend-react": "^0.1.3", - "zustand": "^3.7.1" - }, - "peerDependencies": { - "expo": ">=43.0", - "expo-asset": ">=8.4", - "expo-file-system": ">=11.0", - "expo-gl": ">=11.0", - "react": ">=18.0", - "react-dom": ">=18.0", - "react-native": ">=0.64", - "three": ">=0.133" + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" }, - "peerDependenciesMeta": { - "expo": { - "optional": true - }, - "expo-asset": { - "optional": true - }, - "expo-file-system": { - "optional": true - }, - "expo-gl": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-three/fiber/node_modules/scheduler": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", - "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "node_modules/@jest/test-sequencer/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "loose-envify": "^1.1.0" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-three/postprocessing": { - "version": "2.15.11", - "resolved": "https://registry.npmjs.org/@react-three/postprocessing/-/postprocessing-2.15.11.tgz", - "integrity": "sha512-XQJxhk/hsbzUCLagd8V4pg28iy+UMkYeFFL7BOdlSM1TgAorNzMim+Wu5zI6fbAaGMpmwk7PCbOZN5YPgD0BRQ==", + "node_modules/@jest/test-sequencer/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "buffer": "^6.0.3", - "maath": "^0.6.0", - "n8ao": "^1.6.6", - "postprocessing": "^6.32.1", - "three-stdlib": "^2.23.4" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, - "peerDependencies": { - "@react-three/fiber": ">=8.0", - "react": ">=18.0", - "three": ">= 0.138.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@react-three/postprocessing/node_modules/maath": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/maath/-/maath-0.6.0.tgz", - "integrity": "sha512-dSb2xQuP7vDnaYqfoKzlApeRcR2xtN8/f7WV/TMAkBC8552TwTLtOO0JTcSygkYMjNDPoo6V01jTw/aPi4JrMw==", - "peerDependencies": { - "@types/three": ">=0.144.0", - "three": ">=0.144.0" - } + "node_modules/@jest/test-sequencer/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/@remix-run/router": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.12.0.tgz", - "integrity": "sha512-2hXv036Bux90e1GXTWSMfNzfDDK8LA8JYEWfyHxzvwdp6GyoWEovKc9cotb3KCKmkdwsIBuFGX7ScTWyiHv7Eg==", - "engines": { - "node": ">=14.0.0" + "node_modules/@jest/test-sequencer/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" } }, - "node_modules/@rollup/plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", - "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "node_modules/@jest/test-sequencer/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.10.4", - "@rollup/pluginutils": "^3.1.0" + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "peerDependenciesMeta": { - "@types/babel__core": { - "optional": true - } + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", - "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "node_modules/@jest/test-sequencer/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "node_modules/@jest/test-sequencer/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "node_modules/@jest/test-sequencer/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 8.0.0" + "node": ">=10" }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/pluginutils/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz", - "integrity": "sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dependencies": { - "type-detect": "4.0.8" + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@surma/rollup-plugin-off-main-thread": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", - "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", - "dependencies": { - "ejs": "^3.1.6", - "json5": "^2.2.0", - "magic-string": "^0.25.0", - "string.prototype.matchall": "^4.0.6" - } + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=0.10.0" } }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", - "engines": { - "node": ">=10" + "node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", - "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", - "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", - "engines": { - "node": ">=10" + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", - "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=6.0.0" } }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", - "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=6.0.0" } }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", - "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=6.0.0" } }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", - "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/@svgr/babel-preset": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", - "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.5.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@svgr/core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", - "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "node_modules/@juggle/resize-observer": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", + "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "node_modules/@mediapipe/tasks-vision": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.8.tgz", + "integrity": "sha512-Rp7ll8BHrKB3wXaRFKhrltwZl1CiXGdibPxuWXvqGnKTnv8fqa/nvftYNuSbf+pbJWKYCXdBtYTITdAUTGGh0Q==" + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "dependencies": { - "@svgr/plugin-jsx": "^5.5.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "eslint-scope": "5.1.1" } }, - "node_modules/@svgr/core/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": ">=10" + "node": ">=8.0.0" } }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", - "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", - "dependencies": { - "@babel/types": "^7.12.6" - }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=4.0" } }, - "node_modules/@svgr/plugin-jsx": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", - "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dependencies": { - "@babel/core": "^7.12.3", - "@svgr/babel-preset": "^5.5.0", - "@svgr/hast-util-to-babel-ast": "^5.5.0", - "svg-parser": "^2.0.2" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">= 8" } }, - "node_modules/@svgr/plugin-svgo": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", - "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", - "dependencies": { - "cosmiconfig": "^7.0.0", - "deepmerge": "^4.2.2", - "svgo": "^1.2.2" - }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">= 8" } }, - "node_modules/@svgr/plugin-svgo/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=10" + "node": ">= 8" } }, - "node_modules/@svgr/webpack": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", - "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz", + "integrity": "sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==", "dependencies": { - "@babel/core": "^7.12.3", - "@babel/plugin-transform-react-constant-elements": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-react": "^7.12.5", - "@svgr/core": "^5.5.0", - "@svgr/plugin-jsx": "^5.5.0", - "@svgr/plugin-svgo": "^5.5.0", - "loader-utils": "^2.0.0" + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.4", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" }, "engines": { - "node": ">=10" + "node": ">= 10.13" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "peerDependencies": { + "@types/webpack": "4.x || 5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <5.0.0", + "webpack": ">=4.43.0 <6.0.0", + "webpack-dev-server": "3.x || 4.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "0.x || 1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } } }, - "node_modules/@svgr/webpack/node_modules/loader-utils": { + "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/loader-utils": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", @@ -3998,2212 +4155,4394 @@ "node": ">=8.9.0" } }, - "node_modules/@swc/helpers": { - "version": "0.4.36", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.36.tgz", - "integrity": "sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q==", + "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dependencies": { - "legacy-swc-helpers": "npm:@swc/helpers@=0.4.14", - "tslib": "^2.4.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, "engines": { - "node": ">= 6" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "engines": { - "node": ">=10.13.0" + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" } }, - "node_modules/@tweenjs/tween.js": { - "version": "18.6.4", - "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", - "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==" - }, - "node_modules/@types/babel__core": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.4.tgz", - "integrity": "sha512-mLnSC22IC4vcWiuObSRjrLd9XcBTGf59vUSoq2jkQDJ/QQ8PMI9rSuzE+aEV8karUMbskw07bKYoUJCKTUaygg==", + "node_modules/@react-pdf/fns": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@react-pdf/fns/-/fns-2.0.1.tgz", + "integrity": "sha512-/vgecczzFYBQFkgUupH+sxXhLWQtBwdwCgweyh25XOlR4NZuaMD/UVUDl4loFHhRQqDMQq37lkTcchh7zzW6ug==", "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "@babel/runtime": "^7.20.13" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.7", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", - "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "node_modules/@react-pdf/font": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/@react-pdf/font/-/font-2.3.7.tgz", + "integrity": "sha512-NoCieWea6c1mCpDBoyjPbUEC1qXa+S/M7+8vYPZ71aTMgX7co3gQc2e6YKwrSQeQP+BsBq3LSVhjI2ETXfcytw==", "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/runtime": "^7.20.13", + "@react-pdf/types": "^2.3.4", + "cross-fetch": "^3.1.5", + "fontkit": "^2.0.2", + "is-url": "^1.2.4" } }, - "node_modules/@types/babel__traverse": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", - "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "node_modules/@react-pdf/image": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@react-pdf/image/-/image-2.2.2.tgz", + "integrity": "sha512-990JvRZuhsnHyAGd7gvmhfr+4/5PAHLH9IgDstaEDLEq2eFAIQFuNM7k3D6kjKgV1mM7Jqif3CWqrcHBF3jrJw==", "dependencies": { - "@babel/types": "^7.20.7" + "@babel/runtime": "^7.20.13", + "@react-pdf/png-js": "^2.2.0", + "cross-fetch": "^3.1.5" } }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "node_modules/@react-pdf/layout": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@react-pdf/layout/-/layout-3.6.3.tgz", + "integrity": "sha512-w6ACZ9o18Q5wbzsY9a4KW2Gqn6Drt3AN/kb/I6SBz/L7PAJ9rPQBIDq/s5qZJ+/WwWy33rcC8WC1givtDhjCHQ==", "dependencies": { - "@types/connect": "*", - "@types/node": "*" + "@babel/runtime": "^7.20.13", + "@react-pdf/fns": "2.0.1", + "@react-pdf/image": "^2.2.2", + "@react-pdf/pdfkit": "^3.0.2", + "@react-pdf/primitives": "^3.0.0", + "@react-pdf/stylesheet": "^4.1.8", + "@react-pdf/textkit": "^4.2.0", + "@react-pdf/types": "^2.3.4", + "@react-pdf/yoga": "^4.1.2", + "cross-fetch": "^3.1.5", + "emoji-regex": "^10.2.1", + "queue": "^6.0.1" } }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "node_modules/@react-pdf/pdfkit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@react-pdf/pdfkit/-/pdfkit-3.0.2.tgz", + "integrity": "sha512-+m5rwNCwyEH6lmnZWpsQJvdqb6YaCCR0nMWrc/KKDwznuPMrGmGWyNxqCja+bQPORcHZyl6Cd/iFL0glyB3QGw==", "dependencies": { - "@types/node": "*" + "@babel/runtime": "^7.20.13", + "@react-pdf/png-js": "^2.2.0", + "browserify-zlib": "^0.2.0", + "crypto-js": "^4.0.0", + "fontkit": "^2.0.2", + "vite-compatible-readable-stream": "^3.6.1" } }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "node_modules/@react-pdf/png-js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@react-pdf/png-js/-/png-js-2.2.0.tgz", + "integrity": "sha512-csZU5lfNW73tq7s7zB/1rWXGro+Z9cQhxtsXwxS418TSszHUiM6PwddouiKJxdGhbVLjRIcuuFVa0aR5cDOC6w==", "dependencies": { - "@types/node": "*" + "browserify-zlib": "^0.2.0" } }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.3.tgz", - "integrity": "sha512-6mfQ6iNvhSKCZJoY6sIG3m0pKkdUcweVNOLuBBKvoWGzl2yRxOJcYOTRyLKt3nxXvBLJWa6QkW//tgbIwJehmA==", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } + "node_modules/@react-pdf/primitives": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@react-pdf/primitives/-/primitives-3.0.1.tgz", + "integrity": "sha512-0HGcknrLNwyhxe+SZCBL29JY4M85mXKdvTZE9uhjNbADGgTc8wVnkc5+e4S/lDvugbVISXyuIhZnYwtK9eDnyQ==" }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, + "node_modules/@react-pdf/render": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@react-pdf/render/-/render-3.2.7.tgz", + "integrity": "sha512-fAgbbAAkVL0hpcf1vUJLHxuPjPBqZuq8nors7fCwvoatBBwOWP9fza7IDPeFKN7+ZOnfmIZzes8Kc/DNHzJohw==", "dependencies": { - "@types/ms": "*" + "@babel/runtime": "^7.20.13", + "@react-pdf/fns": "2.0.1", + "@react-pdf/primitives": "^3.0.0", + "@react-pdf/textkit": "^4.2.0", + "@react-pdf/types": "^2.3.4", + "abs-svg-path": "^0.1.1", + "color-string": "^1.5.3", + "normalize-svg-path": "^1.1.0", + "parse-svg-path": "^0.1.2", + "svg-arc-to-cubic-bezier": "^3.2.0" } }, - "node_modules/@types/draco3d": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.8.tgz", - "integrity": "sha512-hdA2gODc+1X5gG+buH8gMRnQdRTa3vep8+PyGFK9xDQmbdudobP//yXLK+C/SnjGLWHiER2QL+xWjq7qkFuivA==" - }, - "node_modules/@types/eslint": { - "version": "8.44.7", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz", - "integrity": "sha512-f5ORu2hcBbKei97U73mf+l9t4zTGl74IqZ0GQk4oVea/VS8tQZYkUveSYojk+frraAVYId0V2WC9O4PTNru2FQ==", + "node_modules/@react-pdf/renderer": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/@react-pdf/renderer/-/renderer-3.1.14.tgz", + "integrity": "sha512-Qk29uTamH6q+drK/YmiFbuQQ+yutesfIe+wyrsXFoUJUutIiDIaibO6zByMkhWb3M6CMt6NvG3NLHio1OF8U6Q==", "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" + "@babel/runtime": "^7.20.13", + "@react-pdf/font": "^2.3.7", + "@react-pdf/layout": "^3.6.3", + "@react-pdf/pdfkit": "^3.0.2", + "@react-pdf/primitives": "^3.0.0", + "@react-pdf/render": "^3.2.7", + "@react-pdf/types": "^2.3.4", + "events": "^3.3.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "queue": "^6.0.1", + "scheduler": "^0.17.0" + }, + "peerDependencies": { + "react": "^16.8.6 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "node_modules/@react-pdf/stylesheet": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@react-pdf/stylesheet/-/stylesheet-4.1.8.tgz", + "integrity": "sha512-/EuB9RBsH3YYRj8mwzImaul619MvX3rsHNF4h8LnlwDOuBehPA3L/fHrikfPqtJvHqK2ty3GXnkw0HG5SQpMzw==", "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" + "@babel/runtime": "^7.20.13", + "@react-pdf/fns": "2.0.1", + "@react-pdf/types": "^2.3.4", + "color-string": "^1.5.3", + "hsl-to-hex": "^1.0.0", + "media-engine": "^1.0.3", + "postcss-value-parser": "^4.1.0" } }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "node_modules/@react-pdf/textkit": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@react-pdf/textkit/-/textkit-4.2.0.tgz", + "integrity": "sha512-R90pEOW6NdhUx4p99iROvKmwB06IRYdXMhh0QcmUeoPOLe64ZdMfs3LZliNUWgI5fCmq71J+nv868i/EakFPDg==", "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "@babel/runtime": "^7.20.13", + "@react-pdf/fns": "2.0.1", + "hyphen": "^1.6.4", + "unicode-properties": "^1.4.1" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "node_modules/@react-pdf/types": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@react-pdf/types/-/types-2.3.4.tgz", + "integrity": "sha512-vGGz21BTE05EktBbotbd7fjC0Yi8A/lOSIpzd7L7aF1XY+vyIHlQVb35DWCipM1p/6XN4cr9etGAmm1e4Mtmjw==" + }, + "node_modules/@react-pdf/yoga": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@react-pdf/yoga/-/yoga-4.1.2.tgz", + "integrity": "sha512-OlMZkFrJDj4GyKZ70thiObwwPVZ52B7mlPyfzwa+sgwsioqHXg9nMWOO+7SQFNUbbOGagMUu0bCuTv+iXYZuaQ==", "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "@babel/runtime": "^7.20.13" } }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "node_modules/@react-spring/animated": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.6.1.tgz", + "integrity": "sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ==", "dependencies": { - "@types/node": "*" + "@react-spring/shared": "~9.6.1", + "@react-spring/types": "~9.6.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@types/hast": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", - "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", - "dev": true, + "node_modules/@react-spring/core": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.6.1.tgz", + "integrity": "sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ==", "dependencies": { - "@types/unist": "^2" + "@react-spring/animated": "~9.6.1", + "@react-spring/rafz": "~9.6.1", + "@react-spring/shared": "~9.6.1", + "@react-spring/types": "~9.6.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + "node_modules/@react-spring/rafz": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.6.1.tgz", + "integrity": "sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ==" }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "node_modules/@react-spring/shared": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.6.1.tgz", + "integrity": "sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw==", "dependencies": { - "@types/node": "*" + "@react-spring/rafz": "~9.6.1", + "@react-spring/types": "~9.6.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@types/is-hotkey": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.9.tgz", - "integrity": "sha512-ZUK9mvsjXXZo4YtGcEVBVhyN80mbuqId0evT9ni+anA3C291IPIzxU+1JFJ9/vvU0qZhydeuJIpUCn6d0rnsCw==" - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", + "node_modules/@react-spring/three": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.6.1.tgz", + "integrity": "sha512-Tyw2YhZPKJAX3t2FcqvpLRb71CyTe1GvT3V+i+xJzfALgpk10uPGdGaQQ5Xrzmok1340DAeg2pR/MCfaW7b8AA==", + "dependencies": { + "@react-spring/animated": "~9.6.1", + "@react-spring/core": "~9.6.1", + "@react-spring/shared": "~9.6.1", + "@react-spring/types": "~9.6.1" + }, + "peerDependencies": { + "@react-three/fiber": ">=6.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "three": ">=0.126" + } + }, + "node_modules/@react-spring/types": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.6.1.tgz", + "integrity": "sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==" + }, + "node_modules/@react-three/drei": { + "version": "9.88.16", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.88.16.tgz", + "integrity": "sha512-AcDTRVmXL81KYQvEz7XSxUqj0W5s8c5XgtYzAx+ttB86tEAxp3r7DXc6ZZdMAUZyfw5BSPHx9hKMHr4xmoFdPg==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "@mediapipe/tasks-vision": "0.10.8", + "@react-spring/three": "~9.6.1", + "@use-gesture/react": "^10.2.24", + "camera-controls": "^2.4.2", + "cross-env": "^7.0.3", + "detect-gpu": "^5.0.28", + "glsl-noise": "^0.0.0", + "lodash.clamp": "^4.0.3", + "lodash.omit": "^4.5.0", + "lodash.pick": "^4.4.0", + "maath": "^0.9.0", + "meshline": "^3.1.6", + "react-composer": "^5.0.3", + "react-merge-refs": "^1.1.0", + "stats-gl": "^1.0.4", + "stats.js": "^0.17.0", + "suspend-react": "^0.1.3", + "three-mesh-bvh": "^0.6.7", + "three-stdlib": "^2.28.0", + "troika-three-text": "^0.47.2", + "utility-types": "^3.10.0", + "uuid": "^9.0.1", + "zustand": "^3.5.13" + }, + "peerDependencies": { + "@react-three/fiber": ">=8.0", + "react": ">=18.0", + "react-dom": ">=18.0", + "three": ">=0.137" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber": { + "version": "8.15.11", + "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.15.11.tgz", + "integrity": "sha512-jOJjrjVMBJQwIK6Uirc3bErUCTiclbS2alJG1eU8pV1jIwDZwPwcfHzSi2TautxoA4ddMt5DmlpatK4rIqM4jA==", + "dependencies": { + "@babel/runtime": "^7.17.8", + "@types/react-reconciler": "^0.26.7", + "@types/webxr": "*", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "its-fine": "^1.0.6", + "react-reconciler": "^0.27.0", + "react-use-measure": "^2.1.1", + "scheduler": "^0.21.0", + "suspend-react": "^0.1.3", + "zustand": "^3.7.1" + }, + "peerDependencies": { + "expo": ">=43.0", + "expo-asset": ">=8.4", + "expo-file-system": ">=11.0", + "expo-gl": ">=11.0", + "react": ">=18.0", + "react-dom": ">=18.0", + "react-native": ">=0.64", + "three": ">=0.133" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + }, + "expo-asset": { + "optional": true + }, + "expo-file-system": { + "optional": true + }, + "expo-gl": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber/node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/@react-three/postprocessing": { + "version": "2.15.11", + "resolved": "https://registry.npmjs.org/@react-three/postprocessing/-/postprocessing-2.15.11.tgz", + "integrity": "sha512-XQJxhk/hsbzUCLagd8V4pg28iy+UMkYeFFL7BOdlSM1TgAorNzMim+Wu5zI6fbAaGMpmwk7PCbOZN5YPgD0BRQ==", + "dependencies": { + "buffer": "^6.0.3", + "maath": "^0.6.0", + "n8ao": "^1.6.6", + "postprocessing": "^6.32.1", + "three-stdlib": "^2.23.4" + }, + "peerDependencies": { + "@react-three/fiber": ">=8.0", + "react": ">=18.0", + "three": ">= 0.138.0" + } + }, + "node_modules/@react-three/postprocessing/node_modules/maath": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.6.0.tgz", + "integrity": "sha512-dSb2xQuP7vDnaYqfoKzlApeRcR2xtN8/f7WV/TMAkBC8552TwTLtOO0JTcSygkYMjNDPoo6V01jTw/aPi4JrMw==", + "peerDependencies": { + "@types/three": ">=0.144.0", + "three": ">=0.144.0" + } + }, + "node_modules/@remix-run/router": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.12.0.tgz", + "integrity": "sha512-2hXv036Bux90e1GXTWSMfNzfDDK8LA8JYEWfyHxzvwdp6GyoWEovKc9cotb3KCKmkdwsIBuFGX7ScTWyiHv7Eg==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz", + "integrity": "sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "dependencies": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "dependencies": { + "@babel/types": "^7.12.6" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "dependencies": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "dependencies": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-svgo/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/webpack/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.4.36", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.36.tgz", + "integrity": "sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q==", + "dependencies": { + "legacy-swc-helpers": "npm:@swc/helpers@=0.4.14", + "tslib": "^2.4.0" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@tweenjs/tween.js": { + "version": "18.6.4", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", + "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==" + }, + "node_modules/@types/babel__core": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.4.tgz", + "integrity": "sha512-mLnSC22IC4vcWiuObSRjrLd9XcBTGf59vUSoq2jkQDJ/QQ8PMI9rSuzE+aEV8karUMbskw07bKYoUJCKTUaygg==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.7", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", + "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.3.tgz", + "integrity": "sha512-6mfQ6iNvhSKCZJoY6sIG3m0pKkdUcweVNOLuBBKvoWGzl2yRxOJcYOTRyLKt3nxXvBLJWa6QkW//tgbIwJehmA==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/draco3d": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.8.tgz", + "integrity": "sha512-hdA2gODc+1X5gG+buH8gMRnQdRTa3vep8+PyGFK9xDQmbdudobP//yXLK+C/SnjGLWHiER2QL+xWjq7qkFuivA==" + }, + "node_modules/@types/eslint": { + "version": "8.44.7", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz", + "integrity": "sha512-f5ORu2hcBbKei97U73mf+l9t4zTGl74IqZ0GQk4oVea/VS8tQZYkUveSYojk+frraAVYId0V2WC9O4PTNru2FQ==", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hast": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz", + "integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/is-hotkey": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.9.tgz", + "integrity": "sha512-ZUK9mvsjXXZo4YtGcEVBVhyN80mbuqId0evT9ni+anA3C291IPIzxU+1JFJ9/vvU0qZhydeuJIpUCn6d0rnsCw==" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.11", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", + "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jest/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, + "node_modules/@types/lodash": { + "version": "4.14.201", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.201.tgz", + "integrity": "sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==" + }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.1.tgz", + "integrity": "sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.9.tgz", + "integrity": "sha512-meK88cx/sTalPSLSoCzkiUB4VPIFHmxtXm5FaaqRDqBX2i/Sy8bJ4odsan0b20RBjPh06dAQ+OTTdnyQyhJZyQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/offscreencanvas": { + "version": "2019.7.3", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", + "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" + }, + "node_modules/@types/prismjs": { + "version": "1.26.3", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", + "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.10", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.10.tgz", + "integrity": "sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==" + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", + "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==" + }, + "node_modules/@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/react": { + "version": "18.2.37", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.37.tgz", + "integrity": "sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.15", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.15.tgz", + "integrity": "sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-helmet": { + "version": "6.1.9", + "resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.9.tgz", + "integrity": "sha512-nuOeTefP4yPTWHvjGksCBKb/4hsgJxSX7aSTjTIDFXJIkZ6Wo2Y4/cmE1FO9OlYBrHjKOer/0zLwY7s4qiQBtw==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-reconciler": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz", + "integrity": "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.6.tgz", + "integrity": "sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==" + }, + "node_modules/@types/semver": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", + "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" + }, + "node_modules/@types/stats.js": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", + "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==" + }, + "node_modules/@types/three": { + "version": "0.152.1", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.152.1.tgz", + "integrity": "sha512-PMOCQnx9JRmq+2OUGTPoY9h1hTWD2L7/nmuW/SyNq1Vbq3Lwt3MNdl3wYSa4DvLTGv62NmIXD9jYdAOwohwJyw==", + "dependencies": { + "@tweenjs/tween.js": "~18.6.4", + "@types/stats.js": "*", + "@types/webxr": "*", + "fflate": "~0.6.9", + "lil-gui": "~0.17.0" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.6.tgz", + "integrity": "sha512-HYtNooPvUY9WAVRBr4u+4Qa9fYD1ze2IUlAD3HoA6oehn1taGwBx3Oa52U4mTslTS+GAExKpaFu39Y5xUEwfjg==" + }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "dev": true + }, + "node_modules/@types/webxr": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.8.tgz", + "integrity": "sha512-9vRpV4nMzuZIdJiu/nHUk1AQV0cguaBI32DIauJXBxpvG3wiXk3VD+kQKx111V7I/YvAoGyJZTyhaWODYEbZ0w==" + }, + "node_modules/@types/ws": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", + "integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "16.0.8", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.8.tgz", + "integrity": "sha512-1GwLEkmFafeb/HbE6pC7tFlgYSQ4Iqh2qlWCq8xN+Qfaiaxr2PcLfuhfRFRYqI6XJyeFoLYyKnhFbNsst9FMtQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "dependencies": { + "@typescript-eslint/utils": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@use-gesture/core": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.0.tgz", + "integrity": "sha512-rh+6MND31zfHcy9VU3dOZCqGY511lvGcfyJenN4cWZe0u1BH6brBpBddLVXhF2r4BMqWbvxfsbL7D287thJU2A==" + }, + "node_modules/@use-gesture/react": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.0.tgz", + "integrity": "sha512-3zc+Ve99z4usVP6l9knYVbVnZgfqhKah7sIG+PS2w+vpig2v2OLct05vs+ZXMzwxdNCMka8B+8WlOo0z6Pn6DA==", + "dependencies": { + "@use-gesture/core": "10.3.0" + }, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abs-svg-path": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz", + "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dependencies": { - "@types/istanbul-lib-coverage": "*" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dependencies": { - "@types/istanbul-lib-report": "*" + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } }, - "node_modules/@types/lodash": { - "version": "4.14.201", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.201.tgz", - "integrity": "sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==" + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } }, - "node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dev": true, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { - "@types/unist": "^2" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", - "dev": true + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/argparse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/@types/node": { - "version": "20.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.1.tgz", - "integrity": "sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA==", + "node_modules/array.prototype.reduce": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz", + "integrity": "sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==", "dependencies": { - "undici-types": "~5.26.4" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/node-forge": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.9.tgz", - "integrity": "sha512-meK88cx/sTalPSLSoCzkiUB4VPIFHmxtXm5FaaqRDqBX2i/Sy8bJ4odsan0b20RBjPh06dAQ+OTTdnyQyhJZyQ==", + "node_modules/array.prototype.tosorted": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", + "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", "dependencies": { - "@types/node": "*" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" } }, - "node_modules/@types/offscreencanvas": { - "version": "2019.7.3", - "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", - "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==" - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/parse5": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", - "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" - }, - "node_modules/@types/prismjs": { - "version": "1.26.3", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", - "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.10", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.10.tgz", - "integrity": "sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==" - }, - "node_modules/@types/q": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", - "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==" - }, - "node_modules/@types/qs": { - "version": "6.9.10", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", - "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "node_modules/@types/react": { - "version": "18.2.37", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.37.tgz", - "integrity": "sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/react-dom": { - "version": "18.2.15", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.15.tgz", - "integrity": "sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==", + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, "dependencies": { - "@types/react": "*" + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" } }, - "node_modules/@types/react-helmet": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.9.tgz", - "integrity": "sha512-nuOeTefP4yPTWHvjGksCBKb/4hsgJxSX7aSTjTIDFXJIkZ6Wo2Y4/cmE1FO9OlYBrHjKOer/0zLwY7s4qiQBtw==", + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", "dev": true, "dependencies": { - "@types/react": "*" + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" } }, - "node_modules/@types/react-reconciler": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz", - "integrity": "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==", - "dependencies": { - "@types/react": "*" - } + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" }, - "node_modules/@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", "dependencies": { - "@types/node": "*" + "has-symbols": "^1.0.3" } }, - "node_modules/@types/scheduler": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.6.tgz", - "integrity": "sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==" + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/@types/semver": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", - "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==" + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "node_modules/autoprefixer": { + "version": "10.4.16", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", + "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "@types/mime": "^1", - "@types/node": "*" + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001538", + "fraction.js": "^4.3.6", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dependencies": { - "@types/express": "*" + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "engines": { + "node": ">=4" } }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", "dependencies": { - "@types/node": "*" + "dequal": "^2.0.3" } }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" - }, - "node_modules/@types/stats.js": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", - "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==" - }, - "node_modules/@types/three": { - "version": "0.152.1", - "resolved": "https://registry.npmjs.org/@types/three/-/three-0.152.1.tgz", - "integrity": "sha512-PMOCQnx9JRmq+2OUGTPoY9h1hTWD2L7/nmuW/SyNq1Vbq3Lwt3MNdl3wYSa4DvLTGv62NmIXD9jYdAOwohwJyw==", + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", "dependencies": { - "@tweenjs/tween.js": "~18.6.4", - "@types/stats.js": "*", - "@types/webxr": "*", - "fflate": "~0.6.9", - "lil-gui": "~0.17.0" + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/@types/trusted-types": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.6.tgz", - "integrity": "sha512-HYtNooPvUY9WAVRBr4u+4Qa9fYD1ze2IUlAD3HoA6oehn1taGwBx3Oa52U4mTslTS+GAExKpaFu39Y5xUEwfjg==" - }, - "node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", - "dev": true - }, - "node_modules/@types/webxr": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.8.tgz", - "integrity": "sha512-9vRpV4nMzuZIdJiu/nHUk1AQV0cguaBI32DIauJXBxpvG3wiXk3VD+kQKx111V7I/YvAoGyJZTyhaWODYEbZ0w==" - }, - "node_modules/@types/ws": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", - "integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==", + "node_modules/babel-loader": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", "dependencies": { - "@types/node": "*" + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" } }, - "node_modules/@types/yargs": { - "version": "16.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.8.tgz", - "integrity": "sha512-1GwLEkmFafeb/HbE6pC7tFlgYSQ4Iqh2qlWCq8xN+Qfaiaxr2PcLfuhfRFRYqI6XJyeFoLYyKnhFbNsst9FMtQ==", + "node_modules/babel-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dependencies": { - "@types/yargs-parser": "*" + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" } }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "dependencies": { - "yallist": "^4.0.0" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">=10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "dependencies": { - "lru-cache": "^6.0.0" + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" }, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "engines": { "node": ">=10" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "node_modules/babel-plugin-named-asset-import": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "peerDependencies": { + "@babel/core": "^7.1.0" + } }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", - "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", + "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", "dependencies": { - "@typescript-eslint/utils": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.3", + "semver": "^6.3.1" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", + "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "@babel/helper-define-polyfill-provider": "^0.4.3", + "core-js-compat": "^3.33.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", + "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.3" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "node_modules/babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@babel/core": "^7.0.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node_modules/babel-preset-react-app": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", + "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-transform-flow-strip-types": "^7.16.0", + "@babel/plugin-transform-react-display-name": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "node_modules/bfj": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", + "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", "dependencies": { - "yallist": "^4.0.0" + "bluebird": "^3.7.2", + "check-types": "^11.2.3", + "hoopy": "^0.1.4", + "jsonpath": "^1.1.1", + "tryer": "^1.0.1" }, "engines": { - "node": ">=10" + "node": ">= 8.0.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, + "require-from-string": "^2.0.2" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "engines": { - "node": ">=10" + "node": "*" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } }, - "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": ">=8.0.0" + "node": ">= 6" } }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { - "yallist": "^4.0.0" + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "ms": "2.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=0.10.0" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "node_modules/@use-gesture/core": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.0.tgz", - "integrity": "sha512-rh+6MND31zfHcy9VU3dOZCqGY511lvGcfyJenN4cWZe0u1BH6brBpBddLVXhF2r4BMqWbvxfsbL7D287thJU2A==" + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/@use-gesture/react": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.0.tgz", - "integrity": "sha512-3zc+Ve99z4usVP6l9knYVbVnZgfqhKah7sIG+PS2w+vpig2v2OLct05vs+ZXMzwxdNCMka8B+8WlOo0z6Pn6DA==", + "node_modules/body-parser/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dependencies": { - "@use-gesture/core": "10.3.0" + "side-channel": "^1.0.4" }, - "peerDependencies": { - "react": ">= 16.8.0" + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "node_modules/bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" } }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "node_modules/brotli": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", + "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", "dependencies": { - "@xtuc/long": "4.2.2" + "base64-js": "^1.1.2" } }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" } }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" } }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { + "node_modules/browserify-sign": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", "dev": true, "dependencies": { - "event-target-shim": "^5.0.0" + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.4", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" }, "engines": { - "node": ">=6.5" + "node": ">= 4" } }, - "node_modules/abs-svg-path": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz", - "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 6" } }, - "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, "bin": { - "acorn": "bin/acorn" + "browserslist": "cli.js" }, "engines": { - "node": ">=0.4.0" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" + "fast-json-stable-stringify": "2.x" }, "engines": { - "node": ">=0.4.0" + "node": ">= 6" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "peerDependencies": { - "acorn": "^8" + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dependencies": { + "node-int64": "^0.4.0" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "engines": { - "node": ">=0.4.0" - } + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "engines": { - "node": ">= 10.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/adjust-sourcemap-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", - "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "dependencies": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { - "node": ">=8.9" + "node": ">= 0.8" } }, - "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, - "engines": { - "node": ">=8.9.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "engines": { - "node": ">= 6.0.0" + "node": ">=6" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/camera-controls": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-2.7.3.tgz", + "integrity": "sha512-L4mxjBd3u8qiOLozdWrH2P8ZybSsDXBF7iyNyqNEFJhPUkovmuARWR8JTc1B/qlclOIg6FvZZA/0uAZMMim0mw==", "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "three": ">=0.126.1" } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" } }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "node_modules/caniuse-lite": { + "version": "1.0.30001563", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz", + "integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { - "type-fest": "^0.21.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dependencies": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "engines": { "node": ">=10" - }, + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/check-types": { + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==" + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "color-convert": "^2.0.1" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=8" + "node": ">= 8.10.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "engines": { - "node": ">= 8" + "node": ">=6.0" } }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "node_modules/argparse/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, + "node_modules/clean-css": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", + "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", "dependencies": { - "dequal": "^2.0.3" + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=12" } }, - "node_modules/array-flatten": { + "node_modules/clone": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "engines": { + "node": ">=0.8" + } }, - "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-string": "^1.0.7" - }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "engines": { - "node": ">=8" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 4.0" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "color-convert": "^1.9.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/array.prototype.reduce": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz", - "integrity": "sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==", + "node_modules/coa/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, + "color-name": "1.1.3" + } + }, + "node_modules/coa/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/coa/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.8.0" } }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", - "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" + "node_modules/coa/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "node_modules/coa/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" + "has-flag": "^3.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "dev": true, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" } }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" }, - "node_modules/asynciterator.prototype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", - "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { - "has-symbols": "^1.0.3" + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "engines": { - "node": ">= 4.0.0" + "node": ">= 12" } }, - "node_modules/autoprefixer": { - "version": "10.4.16", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", - "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dependencies": { - "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001538", - "fraction.js": "^4.3.6", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" + "mime-db": ">= 1.43.0 < 2" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" }, - "peerDependencies": { - "postcss": "^8.1.0" + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8" } }, - "node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", + "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "engines": { - "node": ">=4" + "node": ">=0.8" } }, - "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", "dependencies": { - "dequal": "^2.0.3" + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" } }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" + "safe-buffer": "5.2.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" + "node": ">= 0.6" } }, - "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", - "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" + "node": ">= 0.6" } }, - "node_modules/babel-loader/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { - "node": ">=8.9.0" + "node": ">= 0.6" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-js": { + "version": "3.33.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.2.tgz", + "integrity": "sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "node_modules/core-js-compat": { + "version": "3.33.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.2.tgz", + "integrity": "sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw==", "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" + "browserslist": "^4.22.1" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" + "node_modules/core-js-pure": { + "version": "3.33.2", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.2.tgz", + "integrity": "sha512-a8zeCdyVk7uF2elKIGz67AjcXOxjRbwOLz8SbklEso1V+2DoW4OkAMZN9S9GBgvZIaqQi/OemFX4OiSoQEmg1Q==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", "dependencies": { "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", + "import-fresh": "^3.1.0", "parse-json": "^5.0.0", "path-type": "^4.0.0", - "yaml": "^1.10.0" + "yaml": "^1.7.2" }, "engines": { - "node": ">=10" - } - }, - "node_modules/babel-plugin-named-asset-import": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", - "peerDependencies": { - "@babel/core": "^7.1.0" + "node": ">=8" } }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", - "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.3", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" } }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", - "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3", - "core-js-compat": "^3.33.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", - "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, - "node_modules/babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", - "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "bin": { + "create-jest": "bin/create-jest.js" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/babel-preset-react-app": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", - "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "node_modules/create-jest/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "@babel/core": "^7.16.0", - "@babel/plugin-proposal-class-properties": "^7.16.0", - "@babel/plugin-proposal-decorators": "^7.16.4", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", - "@babel/plugin-proposal-numeric-separator": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-private-methods": "^7.16.0", - "@babel/plugin-transform-flow-strip-types": "^7.16.0", - "@babel/plugin-transform-react-display-name": "^7.16.0", - "@babel/plugin-transform-runtime": "^7.16.4", - "@babel/preset-env": "^7.16.4", - "@babel/preset-react": "^7.16.0", - "@babel/preset-typescript": "^7.16.0", - "@babel/runtime": "^7.16.3", - "babel-plugin-macros": "^3.1.0", - "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "node_modules/create-jest/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "node_modules/bfj": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", - "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", "dependencies": { - "bluebird": "^3.7.2", - "check-types": "^11.2.3", - "hoopy": "^0.1.4", - "jsonpath": "^1.1.1", - "tryer": "^1.0.1" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">= 8.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/bidi-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", - "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "node_modules/create-jest/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/create-jest/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "require-from-string": "^2.0.2" + "@types/yargs-parser": "*" } }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "node_modules/create-jest/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, "engines": { - "node": "*" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, "engines": { - "node": ">=8" + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "node-fetch": "^2.6.12" } }, - "node_modules/bl/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" }, "engines": { - "node": ">= 6" + "node": "*" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "node_modules/css-blank-pseudo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-blank-pseudo": "dist/cli.cjs" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" + "node_modules/css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" } }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/css-has-pseudo": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-has-pseudo": "dist/cli.cjs" }, "engines": { - "node": ">=0.10.0" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "node_modules/css-loader": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", "dependencies": { - "side-channel": "^1.0.4" + "icss-utils": "^5.1.0", + "postcss": "^8.4.21", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" }, "engines": { - "node": ">=0.6" + "node": ">= 12.13.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" } }, - "node_modules/bonjour-service": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", - "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "node_modules/css-loader/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/css-loader/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/css-loader/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", "dependencies": { - "fill-range": "^7.0.1" + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": ">=8" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + } } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } }, - "node_modules/brotli": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", - "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dependencies": { - "base64-js": "^1.1.2" + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/browser-process-hrtime": { + "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, + "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "node_modules/css-prefers-color-scheme": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", + "bin": { + "css-prefers-color-scheme": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", - "dev": true, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", - "safe-buffer": "^5.2.1" + "mdn-data": "2.0.4", + "source-map": "^0.6.1" }, "engines": { - "node": ">= 4" + "node": ">=8.0.0" } }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dependencies": { - "pako": "~1.0.5" + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "node_modules/cssdb": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.9.0.tgz", + "integrity": "sha512-WPMT9seTQq6fPAa1yN4zjgZZeoTriSN2LqW9C+otjar12DQIWA4LuSfFrvFJiKp4oD0xIk1vumDLw8K9ur4NBw==", "funding": [ { "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" + "url": "https://opencollective.com/csstools" }, { "type": "github", - "url": "https://github.com/sponsors/ai" + "url": "https://github.com/sponsors/csstools" } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" - }, + ] + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "bin": { - "browserslist": "cli.js" + "cssesc": "bin/cssesc" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">=4" } }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "node_modules/cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", "dependencies": { - "node-int64": "^0.4.0" + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, "engines": { - "node": ">=6" + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dependencies": { + "cssom": "~0.3.6" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, - "node_modules/bytes": { + "node_modules/csstype": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=10" } }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "node_modules/data-urls/node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "punycode": "^2.1.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dev": true, + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, "engines": { "node": ">=10" }, @@ -6211,854 +8550,1097 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, "engines": { - "node": ">= 6" + "node": ">=4.0.0" } }, - "node_modules/camera-controls": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-2.7.3.tgz", - "integrity": "sha512-L4mxjBd3u8qiOLozdWrH2P8ZybSsDXBF7iyNyqNEFJhPUkovmuARWR8JTc1B/qlclOIg6FvZZA/0uAZMMim0mw==", - "peerDependencies": { - "three": ">=0.126.1" + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001563", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz", - "integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } }, - "node_modules/capital-case": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", - "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3", - "upper-case-first": "^2.0.2" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/case-sensitive-paths-webpack-plugin": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", - "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">=4" + "node": ">=0.4.0" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=6" } }, - "node_modules/change-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", - "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, "dependencies": { - "camel-case": "^4.1.2", - "capital-case": "^1.0.4", - "constant-case": "^3.0.4", - "dot-case": "^3.0.4", - "header-case": "^2.0.4", - "no-case": "^3.0.4", - "param-case": "^3.0.4", - "pascal-case": "^3.1.2", - "path-case": "^3.0.4", - "sentence-case": "^3.0.4", - "snake-case": "^3.0.4", - "tslib": "^2.0.3" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "engines": { - "node": ">=10" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/detect-gpu": { + "version": "5.0.37", + "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.37.tgz", + "integrity": "sha512-EraWs84faI4iskB4qvE39bevMIazEvd1RpoyGLOBesRLbiz6eMeJqqRPHjEFClfRByYZzi9IzU35rBXIO76oDw==", + "dependencies": { + "webgl-constants": "^1.1.1" } }, - "node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": ">=8" } }, - "node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "engines": { + "node": ">=8" } }, - "node_modules/check-types": { - "version": "11.2.3", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", - "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==" + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "address": "^1.0.1", + "debug": "^2.6.0" }, - "engines": { - "node": ">= 8.10.0" + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "engines": { + "node": ">= 4.2.1" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/dfa": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", + "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true, "engines": { - "node": ">=6.0" + "node": ">=0.3.1" } }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, - "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" - }, - "node_modules/classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true }, - "node_modules/clean-css": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", - "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dependencies": { - "source-map": "~0.6.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">= 10.0" + "node": ">=8" } }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node_modules/direction": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz", + "integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "engines": { - "node": ">=0.8" - } + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" }, - "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, "engines": { "node": ">=6" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "node": ">=6.0.0" } }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" + "utila": "~0.4" } }, - "node_modules/coa/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" } }, - "node_modules/coa/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/coa/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" + "node_modules/domain-browser": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", + "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://bevry.me/fund" } }, - "node_modules/coa/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] }, - "node_modules/coa/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "deprecated": "Use your platform's native DOMException instead", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, "engines": { - "node": ">=0.8.0" + "node": ">=8" } }, - "node_modules/coa/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/coa/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dependencies": { - "has-flag": "^3.0.0" + "domelementtype": "^2.2.0" }, "engines": { - "node": ">=4" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dependencies": { - "color-name": "~1.1.4" + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" }, - "engines": { - "node": ">=7.0.0" + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "no-case": "^3.0.4", + "tslib": "^2.0.3" } }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/draco3d": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.6.tgz", + "integrity": "sha512-+3NaRjWktb5r61ZFoDejlykPEFKT5N/LkbXsaddlw6xNSXBanUYpFc2AXXpbJDilPHazcSreU/DpQIaxfX0NfQ==" + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", "dependencies": { - "delayed-stream": "~1.0.0" + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" }, "engines": { - "node": ">= 0.8" + "node": ">=0.10.0" } }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "node_modules/electron-to-chromium": { + "version": "1.4.588", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.588.tgz", + "integrity": "sha512-soytjxwbgcCu7nh5Pf4S2/4wa6UIu+A3p03U2yVr53qGxi1/VTR3ENI+p50v+UxqqZAfl48j3z55ud7VHIOr9w==" + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, + "engines": { + "node": ">=12" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } + "node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" }, - "node_modules/common-path-prefix": { + "node_modules/emojis-list": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "engines": { - "node": ">=4.0.0" + "node": ">= 4" } }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" + "once": "^1.4.0" } }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=10.13.0" } }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "node_modules/enhanced-resolve/node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "engines": { - "node": ">= 0.8" + "node": ">=6" } }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dependencies": { - "ms": "2.0.0" + "is-arrayish": "^0.2.1" } }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dependencies": { + "stackframe": "^1.3.4" + } }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "node_modules/es-abstract": { + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/compute-scroll-into-view": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", - "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==" + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "node_modules/es-iterator-helpers": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", + "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.1", + "es-set-tostringtag": "^2.0.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.0.1" + } }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "node_modules/es-set-tostringtag": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "dependencies": { + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" + }, "engines": { - "node": ">=0.8" + "node": ">= 0.4" } }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constant-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", - "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3", - "upper-case": "^2.0.2" + "hasown": "^2.0.0" } }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dependencies": { - "safe-buffer": "5.2.1" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "engines": { - "node": ">= 0.6" + "node": ">=6" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/core-js": { - "version": "3.33.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.2.tgz", - "integrity": "sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ==", - "hasInstallScript": true, + "node": ">=10" + }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/core-js-compat": { - "version": "3.33.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.2.tgz", - "integrity": "sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw==", + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dependencies": { - "browserslist": "^4.22.1" + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/core-js-pure": { - "version": "3.33.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.2.tgz", - "integrity": "sha512-a8zeCdyVk7uF2elKIGz67AjcXOxjRbwOLz8SbklEso1V+2DoW4OkAMZN9S9GBgvZIaqQi/OemFX4OiSoQEmg1Q==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "node_modules/eslint": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", + "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.54.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, - "node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "node_modules/eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" }, "engines": { - "node": ">=8" + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.0" } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "dependencies": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" } }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "node_modules/eslint-plugin-import": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", + "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" }, "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { - "node-fetch": "^2.6.12" + "ms": "^2.1.1" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "esutils": "^2.0.2" }, "engines": { - "node": ">= 8" + "node": ">=0.10.0" } }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "@typescript-eslint/experimental-utils": "^5.0.0" }, "engines": { - "node": "*" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } } }, - "node_modules/crypto-js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, "engines": { - "node": ">=8" + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/css-blank-pseudo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", - "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "bin": { - "css-blank-pseudo": "dist/cli.cjs" + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" }, "engines": { - "node": "^12 || ^14 || >=16" + "node": ">=4" }, "peerDependencies": { - "postcss": "^8.4" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=10" }, "peerDependencies": { - "postcss": "^8.0.9" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, - "node_modules/css-has-pseudo": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", - "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "bin": { - "css-has-pseudo": "dist/cli.cjs" + "esutils": "^2.0.2" }, "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" + "node": ">=0.10.0" } }, - "node_modules/css-loader": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", - "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.21", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.3", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "engines": { - "node": ">= 12.13.0" + "bin": { + "resolve": "bin/resolve" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/css-loader/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-testing-library": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", + "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", "dependencies": { - "yallist": "^4.0.0" + "@typescript-eslint/utils": "^5.58.0" }, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", + "npm": ">=6" + }, + "peerDependencies": { + "eslint": "^7.5.0 || ^8.0.0" } }, - "node_modules/css-loader/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/css-loader/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", - "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "node_modules/eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", "dependencies": { - "cssnano": "^5.0.6", - "jest-worker": "^27.0.2", - "postcss": "^8.3.5", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" }, "engines": { "node": ">= 12.13.0" @@ -7068,24 +9650,11 @@ "url": "https://opencollective.com/webpack" }, "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0", "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - } } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { + "node_modules/eslint-webpack-plugin/node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", @@ -7100,7 +9669,7 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { + "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", @@ -7111,12 +9680,25 @@ "ajv": "^8.8.2" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, - "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { + "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", @@ -7134,490 +9716,577 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/eslint-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/css-prefers-color-scheme": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", - "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", - "bin": { - "css-prefers-color-scheme": "dist/cli.cjs" + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" }, "engines": { - "node": "^12 || ^14 || >=16" + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dependencies": { + "type-fest": "^0.20.2" }, - "peerDependencies": { - "postcss": "^8.4" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/fb55" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, - "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dependencies": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" } }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" + "node": ">=0.8.x" } }, - "node_modules/cssdb": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.9.0.tgz", - "integrity": "sha512-WPMT9seTQq6fPAa1yN4zjgZZeoTriSN2LqW9C+otjar12DQIWA4LuSfFrvFJiKp4oD0xIk1vumDLw8K9ur4NBw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - } - ] - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, - "node_modules/cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dependencies": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">= 0.8.0" } }, - "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=6" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, - "peerDependencies": { - "postcss": "^8.2.15" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "node_modules/expect/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "css-tree": "^1.1.2" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": ">=8.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "node_modules/expect/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + "node_modules/expect/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node_modules/expect/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" } }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + "node_modules/expect/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "node_modules/expect/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "cssom": "~0.3.6" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - }, - "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" }, "engines": { - "node": ">=10" + "node": ">= 0.10.0" } }, - "node_modules/data-urls/node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" + "ms": "2.0.0" } }, - "node_modules/data-urls/node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" + "side-channel": "^1.0.4" }, "engines": { - "node": ">=10" + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dependencies": { - "ms": "2.1.2" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=8.6.0" } }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, - "node_modules/decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "dev": true, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "reusify": "^1.0.4" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dependencies": { - "mimic-response": "^3.1.0" + "websocket-driver": ">=0.5.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.8.0" } }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dependencies": { + "bser": "2.1.1" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } + "node_modules/fflate": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", + "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==" }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "engines": { - "node": ">=8" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 10.13.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "node_modules/file-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, "engines": { - "node": ">=0.4.0" + "node": ">=8.9.0" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, "engines": { - "node": ">= 0.8" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "engines": { - "node": ">=6" + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" } }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=10" } }, - "node_modules/detect-gpu": { - "version": "5.0.37", - "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.37.tgz", - "integrity": "sha512-EraWs84faI4iskB4qvE39bevMIazEvd1RpoyGLOBesRLbiz6eMeJqqRPHjEFClfRByYZzi9IzU35rBXIO76oDw==", - "dependencies": { - "webgl-constants": "^1.1.1" + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "engines": { + "node": ">= 0.4.0" } }, - "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "dev": true, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, "engines": { "node": ">=8" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "node_modules/filter-obj": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", + "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "node_modules/detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" }, "engines": { - "node": ">= 4.2.1" + "node": ">= 0.8" } }, - "node_modules/detect-port-alt/node_modules/debug": { + "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", @@ -7625,483 +10294,452 @@ "ms": "2.0.0" } }, - "node_modules/detect-port-alt/node_modules/ms": { + "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/dfa": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", - "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==" - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, - "node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dependencies": { - "path-type": "^4.0.0" + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=8" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/direction": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz", - "integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==", - "bin": { - "direction": "cli.js" + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + "node_modules/fontkit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.2.tgz", + "integrity": "sha512-jc4k5Yr8iov8QfS6u8w2CnHWVmbOGtdBtOXMze5Y+QD966Rx6PEVWXSEGwXlsDlKtu1G12cJjcsybnqhSk/+LA==", + "dependencies": { + "@swc/helpers": "^0.4.2", + "brotli": "^1.3.2", + "clone": "^2.1.2", + "dfa": "^1.2.0", + "fast-deep-equal": "^3.1.3", + "restructure": "^3.0.0", + "tiny-inflate": "^1.0.3", + "unicode-properties": "^1.4.0", + "unicode-trie": "^2.0.0" + } }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" }, "engines": { - "node": ">=6" + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/fork-ts-checker-webpack-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { - "esutils": "^2.0.2" + "yallist": "^4.0.0" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" + "node": ">=10" } }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domain-browser": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", - "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==", - "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://bevry.me/fund" } }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] + "node_modules/fork-ts-checker-webpack-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dependencies": { - "webidl-conversions": "^5.0.0" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "engines": { - "node": ">= 4" + "node": "*" }, "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" + "type": "patreon", + "url": "https://github.com/sponsors/rawify" } }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" } }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true }, - "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, "engines": { "node": ">=10" } }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - }, - "node_modules/draco3d": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.6.tgz", - "integrity": "sha512-+3NaRjWktb5r61ZFoDejlykPEFKT5N/LkbXsaddlw6xNSXBanUYpFc2AXXpbJDilPHazcSreU/DpQIaxfX0NfQ==" - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.10.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/electron-to-chromium": { - "version": "1.4.588", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.588.tgz", - "integrity": "sha512-soytjxwbgcCu7nh5Pf4S2/4wa6UIu+A3p03U2yVr53qGxi1/VTR3ENI+p50v+UxqqZAfl48j3z55ud7VHIOr9w==" - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" + "node_modules/fuzzaldrin-plus": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/fuzzaldrin-plus/-/fuzzaldrin-plus-0.6.0.tgz", + "integrity": "sha512-srIDThJHkdp3aPwJpR/HNzYZCRJwm07b/igxseoHSB7qR8e/gQp4F6lMGknE3TQI1Aq14TiFf/wzrHOp9LY/EA==" }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "engines": { - "node": ">= 4" + "node": ">=6.9.0" } }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, - "engines": { - "node": ">=10.13.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/enhanced-resolve/node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "engines": { - "node": ">=6" + "node": ">=8.0.0" } }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dependencies": { - "is-arrayish": "^0.2.1" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "dependencies": { - "stackframe": "^1.3.4" - } + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true }, - "node_modules/es-abstract": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" - }, - "node_modules/es-iterator-helpers": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", - "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { - "asynciterator.prototype": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.1", - "es-set-tostringtag": "^2.0.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.2.1", - "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.0.1" + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, - "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "global-prefix": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dependencies": { - "hasown": "^2.0.0" + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "define-properties": "^1.1.3" }, "engines": { "node": ">= 0.4" @@ -8110,23 +10748,18 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, "engines": { "node": ">=10" }, @@ -8134,549 +10767,579 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "node_modules/glsl-noise": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz", + "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==" + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" + "get-intrinsic": "^1.1.3" }, - "optionalDependencies": { - "source-map": "~0.6.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/eslint": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", - "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.3", - "@eslint/js": "8.54.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" + "duplexer": "^0.1.2" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=10" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-config-react-app": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", - "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", - "dependencies": { - "@babel/core": "^7.16.0", - "@babel/eslint-parser": "^7.16.3", - "@rushstack/eslint-patch": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", - "babel-preset-react-app": "^10.0.1", - "confusing-browser-globals": "^1.0.11", - "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jest": "^25.3.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.27.1", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-testing-library": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "eslint": "^8.0.0" - } + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" } }, - "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dependencies": { - "debug": "^3.2.7" + "get-intrinsic": "^1.2.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "engines": { - "node": ">=4" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-flowtype": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", - "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dependencies": { - "lodash": "^4.17.21", - "string-natural-compare": "^3.0.1" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">=12.0.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@babel/plugin-syntax-flow": "^7.14.5", - "@babel/plugin-transform-react-jsx": "^7.14.9", - "eslint": "^8.1.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-import": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", - "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" }, "engines": { "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "engines": { + "node": ">= 6" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, "dependencies": { - "ms": "^2.1.1" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dependencies": { - "esutils": "^2.0.2" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" + "node_modules/hast-util-embedded": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-2.0.1.tgz", + "integrity": "sha512-QUdSOP1/o+/TxXtpPFXR2mUg2P+ySrmlX7QjwHZCXqMFyYk7YmcGSvqRW+4XgXAoHifdE1t2PwFaQK33TqVjSw==", + "dev": true, + "dependencies": { + "hast-util-is-element": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eslint-plugin-jest": { - "version": "25.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", - "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "node_modules/hast-util-from-parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", + "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "^5.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", - "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "node_modules/hast-util-is-element": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz", + "integrity": "sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.23.2", - "aria-query": "^5.3.0", - "array-includes": "^3.1.7", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "=4.7.0", - "axobject-query": "^3.2.1", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.15", - "hasown": "^2.0.0", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7" - }, - "engines": { - "node": ">=4.0" + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0" }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/eslint-plugin-react": { - "version": "7.33.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", - "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "node_modules/hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dev": true, "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.12", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.4", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.8" - }, - "engines": { - "node": ">=4" + "@types/hast": "^2.0.0" }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "engines": { - "node": ">=10" + "node_modules/hast-util-raw": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", + "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/hast-util-to-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", + "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", + "dev": true, "dependencies": { - "esutils": "^2.0.2" + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "node_modules/hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "dev": true, "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "bin": { - "semver": "bin/semver.js" + "he": "bin/he" } }, - "node_modules/eslint-plugin-testing-library": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", - "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", "dependencies": { - "@typescript-eslint/utils": "^5.58.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0", - "npm": ">=6" - }, - "peerDependencies": { - "eslint": "^7.5.0 || ^8.0.0" + "capital-case": "^1.0.4", + "tslib": "^2.0.3" } }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">= 6.0.0" } }, - "node_modules/eslint-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", - "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dependencies": { - "@types/eslint": "^7.29.0 || ^8.4.1", - "jest-worker": "^28.0.2", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0", - "webpack": "^5.0.0" + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" + "safe-buffer": "~5.1.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", - "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "node_modules/hsl-to-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-to-hex/-/hsl-to-hex-1.0.0.tgz", + "integrity": "sha512-K6GVpucS5wFf44X0h2bLVRDsycgJmf9FF2elg+CrqD8GcFU8c6vYhgXn8NjUkFCwj+xDFb70qgLbTUm6sxwPmA==", "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "hsl-to-rgb-for-reals": "^1.1.0" + } + }, + "node_modules/hsl-to-rgb-for-reals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hsl-to-rgb-for-reals/-/hsl-to-rgb-for-reals-1.1.1.tgz", + "integrity": "sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg==" + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dependencies": { + "whatwg-encoding": "^1.0.5" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=10" } }, - "node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "node_modules/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] }, - "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-to-image": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz", + "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==" + }, + "node_modules/html-void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", + "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">=10.13.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "webpack": "^5.20.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/html-webpack-plugin/node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], "dependencies": { - "has-flag": "^4.0.0" + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">= 0.8" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dependencies": { - "is-glob": "^4.0.3" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=8.0.0" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dependencies": { - "type-fest": "^0.20.2" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 6" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "dependencies": { - "argparse": "^2.0.1" + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "engines": { "node": ">=10" }, @@ -8684,758 +11347,787 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/http-proxy/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "agent-base": "6", + "debug": "4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">= 6" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "engines": { - "node": ">=4" + "node": ">=10.17.0" } }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } + "node_modules/hyphen": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/hyphen/-/hyphen-1.9.1.tgz", + "integrity": "sha512-fIPVvM6BUW+878xne+wwIcBjMxeKpoADmxNTjKMocUQWiGOvwyEfZEG95IeL/t4Su6nbfbXeYDUnz62pxzLPmw==" }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dependencies": { - "estraverse": "^5.2.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=4.0" + "node": ">=0.10.0" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "engines": { - "node": ">=4.0" + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "dependencies": { + "harmony-reflect": "^1.4.6" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "engines": { - "node": ">= 0.6" + "node": ">= 4" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, - "engines": { - "node": ">=6" + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" } }, - "node_modules/events": { + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==" + }, + "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, "engines": { - "node": ">=0.8.x" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "engines": { - "node": ">= 0.8.0" + "node": ">=0.8.19" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "engines": { - "node": ">=6" + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/internal-slot": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.4" } }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, + "node_modules/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", "engines": { - "node": ">= 0.10.0" + "node": ">= 10" } }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, "dependencies": { - "ms": "2.0.0" + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, "dependencies": { - "side-channel": "^1.0.4" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.6" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/extend": { + "node_modules/is-array-buffer": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" }, - "engines": { - "node": ">=8.6.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dependencies": { - "reusify": "^1.0.4" - } + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", "dependencies": { - "websocket-driver": ">=0.5.1" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.8.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dependencies": { - "bser": "2.1.1" + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fflate": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", - "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dependencies": { - "flat-cache": "^3.0.4" + "binary-extensions": "^2.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=8" } }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/file-loader/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "hasown": "^2.0.0" }, - "engines": { - "node": ">=8.9.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/filelist": { + "node_modules/is-decimal": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" }, "engines": { - "node": ">=10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { - "node": ">= 0.4.0" + "node": ">=0.10.0" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", "dependencies": { - "to-regex-range": "^5.0.1" + "call-bind": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { "node": ">=8" } }, - "node_modules/filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", - "dev": true, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" + "node_modules/is-hotkey": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.1.8.tgz", + "integrity": "sha512-qs3NZ1INIS+H+yeo7cD9pDfwYV/jqRh1JG9S9zYrNudkoUQg7OL7ziXqRKu+InFjUIDoP2o6HIkLYMh1pcWgyQ==" + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" - }, - "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/fontkit": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.2.tgz", - "integrity": "sha512-jc4k5Yr8iov8QfS6u8w2CnHWVmbOGtdBtOXMze5Y+QD966Rx6PEVWXSEGwXlsDlKtu1G12cJjcsybnqhSk/+LA==", - "dependencies": { - "@swc/helpers": "^0.4.2", - "brotli": "^1.3.2", - "clone": "^2.1.2", - "dfa": "^1.2.0", - "fast-deep-equal": "^3.1.3", - "restructure": "^3.0.0", - "tiny-inflate": "^1.0.3", - "unicode-properties": "^1.4.0", - "unicode-trie": "^2.0.0" + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", "engines": { - "node": ">=10" + "node": ">=6" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "call-bind": "^1.0.2" }, - "engines": { - "node": ">= 6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "engines": { - "node": ">= 0.6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": "*" + "node": ">= 0.4" }, "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "which-typed-array": "^1.1.11" }, "engines": { - "node": ">=10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" - }, - "node_modules/fs.realpath": { + "node_modules/is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" + "call-bind": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fuzzaldrin-plus": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/fuzzaldrin-plus/-/fuzzaldrin-plus-0.6.0.tgz", - "integrity": "sha512-srIDThJHkdp3aPwJpR/HNzYZCRJwm07b/igxseoHSB7qR8e/gQp4F6lMGknE3TQI1Aq14TiFf/wzrHOp9LY/EA==" - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/get-caller-file": { + "node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=8" } }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=8.0.0" + "node": ">=10" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/istanbul-lib-report/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dependencies": { + "semver": "^7.5.3" + }, "engines": { "node": ">=10" }, @@ -9443,2250 +12135,2741 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "lru-cache": "^6.0.0" }, - "engines": { - "node": ">= 0.4" + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true + "node_modules/istanbul-lib-report/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=10" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dependencies": { - "is-glob": "^4.0.1" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "node_modules/its-fine": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.1.1.tgz", + "integrity": "sha512-v1Ia1xl20KbuSGlwoaGsW0oxsw8Be+TrXweidxD9oT/1lAh6O3K3/GIM95Tt6WCiv6W+h2M7RB1TwdoAjQyyKw==", "dependencies": { - "global-prefix": "^3.0.0" + "@types/react-reconciler": "^0.28.0" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "react": ">=18.0" } }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "node_modules/its-fine/node_modules/@types/react-reconciler": { + "version": "0.28.8", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", + "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" + "@types/react": "*" } }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dependencies": { - "isexe": "^2.0.0" + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" }, "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "jake": "bin/cli.js" + }, "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, "dependencies": { - "define-properties": "^1.1.3" + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/glsl-noise": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz", - "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==" - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "node_modules/jest-changed-files/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "get-intrinsic": "^1.1.3" + "@sinclair/typebox": "^0.27.8" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "node_modules/jest-changed-files/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "duplexer": "^0.1.2" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "node_modules/harmony-reflect": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + "node_modules/jest-changed-files/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/jest-changed-files/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-changed-files/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "node_modules/jest-circus/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/jest-circus/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-circus/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "node_modules/jest-circus/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">= 6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "node_modules/jest-cli/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "node_modules/jest-cli/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "function-bind": "^1.1.2" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hast-util-embedded": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-2.0.1.tgz", - "integrity": "sha512-QUdSOP1/o+/TxXtpPFXR2mUg2P+ySrmlX7QjwHZCXqMFyYk7YmcGSvqRW+4XgXAoHifdE1t2PwFaQK33TqVjSw==", + "node_modules/jest-cli/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-cli/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, "dependencies": { - "hast-util-is-element": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "@types/yargs-parser": "*" } }, - "node_modules/hast-util-from-parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", - "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "hastscript": "^7.0.0", - "property-information": "^6.0.0", - "vfile": "^5.0.0", - "vfile-location": "^4.0.0", - "web-namespaces": "^2.0.0" + "engines": { + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/hast-util-is-element": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz", - "integrity": "sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==", + "node_modules/jest-cli/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hast-util-parse-selector": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", - "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "node_modules/jest-cli/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, "dependencies": { - "@types/hast": "^2.0.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hast-util-raw": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", - "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", + "node_modules/jest-cli/node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "dependencies": { - "@types/hast": "^2.0.0", - "@types/parse5": "^6.0.0", - "hast-util-from-parse5": "^7.0.0", - "hast-util-to-parse5": "^7.0.0", - "html-void-elements": "^2.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hast-util-to-parse5": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", - "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", + "node_modules/jest-cli/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hast-util-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", - "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/jest-cli/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, - "node_modules/hastscript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", - "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/header-case": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", - "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "node_modules/jest-config/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "capital-case": "^1.0.4", - "tslib": "^2.0.3" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "node_modules/jest-config/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, "engines": { - "node": ">= 6.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "node_modules/jest-config/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "node_modules/jest-config/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "node_modules/jest-config/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@types/yargs-parser": "*" } }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/hsl-to-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-to-hex/-/hsl-to-hex-1.0.0.tgz", - "integrity": "sha512-K6GVpucS5wFf44X0h2bLVRDsycgJmf9FF2elg+CrqD8GcFU8c6vYhgXn8NjUkFCwj+xDFb70qgLbTUm6sxwPmA==", + "node_modules/jest-config/node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, "dependencies": { - "hsl-to-rgb-for-reals": "^1.1.0" + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/hsl-to-rgb-for-reals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hsl-to-rgb-for-reals/-/hsl-to-rgb-for-reals-1.1.1.tgz", - "integrity": "sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg==" - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "node_modules/jest-config/node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, "dependencies": { - "whatwg-encoding": "^1.0.5" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/html-entities": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "node_modules/jest-config/node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": ">=12" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/html-to-image": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz", - "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==" - }, - "node_modules/html-void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", - "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/html-webpack-plugin": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", - "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "node_modules/jest-config/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "peerDependencies": { - "webpack": "^5.20.0" + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/html-webpack-plugin/node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "node_modules/jest-config/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], + "node_modules/jest-config/node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/jest-config/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 0.8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + "node_modules/jest-config/node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "node_modules/jest-config/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=8.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "node_modules/jest-config/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-config/node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } + "node": ">=10" } }, - "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "node_modules/jest-config/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/http-proxy/node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "node_modules/jest-config/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, "dependencies": { - "agent-base": "6", - "debug": "4" + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" }, "engines": { - "node": ">= 6" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/hyphen": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/hyphen/-/hyphen-1.9.1.tgz", - "integrity": "sha512-fIPVvM6BUW+878xne+wwIcBjMxeKpoADmxNTjKMocUQWiGOvwyEfZEG95IeL/t4Su6nbfbXeYDUnz62pxzLPmw==" - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "engines": { - "node": "^10 || ^12 || >= 14" + "node_modules/jest-diff/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" }, - "peerDependencies": { - "postcss": "^8.1.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + "node_modules/jest-diff/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", - "dependencies": { - "harmony-reflect": "^1.4.6" - }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "node_modules/jest-diff/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, "engines": { - "node": ">= 4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==" + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "detect-newline": "^3.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/jest-each/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, "engines": { - "node": ">=0.8.19" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/jest-each/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "node_modules/jest-each/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/internal-slot": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", - "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "node_modules/jest-each/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, "engines": { - "node": ">= 10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "node_modules/jest-each/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" }, "engines": { - "node": ">= 0.4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dependencies": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "node_modules/jest-environment-jsdom/node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dependencies": { + "type-detect": "4.0.8" + } }, - "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "node_modules/jest-environment-jsdom/node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dependencies": { - "has-tostringtag": "^1.0.0" + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/jest-environment-jsdom/node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", "dependencies": { - "has-bigints": "^1.0.1" + "@jest/types": "^27.5.1", + "@types/node": "*" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/jest-environment-node/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "node_modules/jest-environment-node/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, "engines": { - "node": ">=4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/jest-environment-node/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-environment-node/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" } }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "node_modules/jest-environment-node/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "hasown": "^2.0.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "dependencies": { - "has-tostringtag": "^1.0.0" + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" }, "engines": { - "node": ">= 0.4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/jest-jasmine2/node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "node_modules/jest-jasmine2/node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", "dependencies": { - "call-bind": "^1.0.2" + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, "engines": { - "node": ">=6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "node_modules/jest-jasmine2/node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", "dependencies": { - "has-tostringtag": "^1.0.0" + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/jest-jasmine2/node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", "dependencies": { - "is-extglob": "^2.1.1" + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-hotkey": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.1.8.tgz", - "integrity": "sha512-qs3NZ1INIS+H+yeo7cD9pDfwYV/jqRh1JG9S9zYrNudkoUQg7OL7ziXqRKu+InFjUIDoP2o6HIkLYMh1pcWgyQ==" - }, - "node_modules/is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, + "node_modules/jest-jasmine2/node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/jest-jasmine2/node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dependencies": { + "type-detect": "4.0.8" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" + "node_modules/jest-jasmine2/node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dependencies": { + "@sinonjs/commons": "^1.7.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, + "node_modules/jest-jasmine2/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "node_modules/jest-jasmine2/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/jest-jasmine2/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "node_modules/jest-jasmine2/node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "node_modules/jest-jasmine2/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "node_modules/jest-jasmine2/node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, "engines": { - "node": ">=6" - } - }, - "node_modules/is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "node_modules/jest-jasmine2/node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", "dependencies": { - "call-bind": "^1.0.2" + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/jest-jasmine2/node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", "dependencies": { - "has-tostringtag": "^1.0.0" + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/jest-jasmine2/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { - "has-symbols": "^1.0.2" + "yallist": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "node_modules/jest-jasmine2/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { - "which-typed-array": "^1.1.11" + "lru-cache": "^6.0.0" }, - "engines": { - "node": ">= 0.4" + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "node_modules/jest-jasmine2/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + "node_modules/jest-jasmine2/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/jest-leak-detector/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "@sinclair/typebox": "^0.27.8" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "node_modules/jest-leak-detector/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, "dependencies": { - "is-docker": "^2.0.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "node_modules/jest-matcher-utils/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" + "node_modules/jest-matcher-utils/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-report/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, "dependencies": { - "yallist": "^4.0.0" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "node_modules/jest-message-util/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "semver": "^7.5.3" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/jest-message-util/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-report/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "node_modules/jest-message-util/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "node_modules/jest-message-util/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "node_modules/jest-mock/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/its-fine": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.1.1.tgz", - "integrity": "sha512-v1Ia1xl20KbuSGlwoaGsW0oxsw8Be+TrXweidxD9oT/1lAh6O3K3/GIM95Tt6WCiv6W+h2M7RB1TwdoAjQyyKw==", + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "@types/react-reconciler": "^0.28.0" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, - "peerDependencies": { - "react": ">=18.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/its-fine/node_modules/@types/react-reconciler": { - "version": "0.28.8", - "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", - "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", + "node_modules/jest-mock/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-mock/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "@types/react": "*" + "@types/yargs-parser": "*" } }, - "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "node_modules/jest-mock/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "jest-resolve": "*" }, "peerDependenciesMeta": { - "node-notifier": { + "jest-resolve": { "optional": true } } }, - "node_modules/jest-changed-files": { + "node_modules/jest-regex-util": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", "dependencies": { "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-changed-files/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/jest-runner/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-runner/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-changed-files/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/jest-runner/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, "engines": { - "node": ">=10.17.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-changed-files/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/jest-runner/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/jest-changed-files/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/jest-runner/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-changed-files/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/jest-runner/node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, "dependencies": { - "path-key": "^3.0.0" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-changed-files/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/jest-runner/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-changed-files/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "node_modules/jest-runner/node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "node_modules/jest-runner/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "node_modules/jest-runner/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "node_modules/jest-runner/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-runner/node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runner/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" }, - "peerDependencies": { - "ts-node": ">=9.0.0" + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "node_modules/jest-runtime/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { - "detect-newline": "^3.0.0" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "node_modules/jest-runtime/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, "dependencies": { - "@jest/types": "^27.5.1", + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "node_modules/jest-runtime/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "node_modules/jest-runtime/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "node_modules/jest-runtime/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "node_modules/jest-runtime/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "micromatch": "^4.0.4", - "walker": "^1.0.7" + "walker": "^1.0.8" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "optionalDependencies": { "fsevents": "^2.3.2" } }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "node_modules/jest-runtime/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "node_modules/jest-runtime/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "node_modules/jest-runtime/node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "node_modules/jest-runtime/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "node_modules/jest-runtime/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "node_modules/jest-runtime/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } + "node": ">=10" } }, - "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "node_modules/jest-runtime/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/jest-resolve-dependencies": { + "node_modules/jest-serializer": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" + "@types/node": "*", + "graceful-fs": "^4.2.9" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "emittery": "^0.8.1", + "expect": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "node_modules/jest-snapshot/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", "slash": "^3.0.0", - "strip-bom": "^4.0.0" + "write-file-atomic": "^4.0.2" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/jest-snapshot/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" + "node_modules/jest-snapshot/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" } }, - "node_modules/jest-runtime/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-runtime/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-runtime/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/jest-snapshot/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/jest-runtime/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "node_modules/jest-snapshot/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "node_modules/jest-snapshot/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "dependencies": { + "@jest/types": "^29.6.3", "@types/node": "*", - "graceful-fs": "^4.2.9" + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "node_modules/jest-snapshot/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-snapshot/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -11694,10 +14877,31 @@ "node": ">=10" } }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-snapshot/node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -11708,10 +14912,39 @@ "node": ">=10" } }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/jest-snapshot/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/jest-util": { "version": "27.5.1", @@ -12020,20 +15253,83 @@ } }, "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.5.1", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", "string-length": "^4.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-watcher/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-worker": { @@ -12063,6 +15359,50 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jest/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/jest/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, "node_modules/jiti": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", @@ -12534,6 +15874,12 @@ "semver": "bin/semver.js" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -12874,13 +16220,269 @@ ], "dependencies": { "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/micromark-factory-title": { + "node_modules/micromark-util-subtokenize": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", "dev": true, "funding": [ { @@ -12893,16 +16495,16 @@ } ], "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" } }, - "node_modules/micromark-factory-whitespace": { + "node_modules/micromark-util-symbol": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", "dev": true, "funding": [ { @@ -12913,18 +16515,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } + ] }, - "node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", "dev": true, "funding": [ { @@ -12935,1520 +16531,1851 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ], + ] + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" } }, - "node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "node_modules/n3": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.17.2.tgz", + "integrity": "sha512-BxSM52wYFqXrbQQT5WUEzKUn6qpYV+2L4XZLfn3Gblz2kwZ09S+QxC33WNdVEQy2djenFL8SNkrjejEKlvI6+Q==", "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], "dependencies": { - "micromark-util-symbol": "^1.0.0" + "queue-microtask": "^1.1.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" } }, - "node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/n8ao": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/n8ao/-/n8ao-1.6.8.tgz", + "integrity": "sha512-3xaBaoMIplgPdBK+9mZefa8stWEoA2673h2734wYMxm/hUkMLENMhzymDe+WZueFQq93ly4xpl5s1NJrQBzFOQ==", + "peerDependencies": { + "postprocessing": ">=6.30.0", + "three": ">=0.137" + } + }, + "node_modules/nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "dev": true + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "lower-case": "^2.0.2", + "tslib": "^2.0.3" } }, - "node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "node_modules/node-abi": { + "version": "3.52.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.52.0.tgz", + "integrity": "sha512-JJ98b02z16ILv7859irtXn4oUaFWADtvkzy2c0IAatNVX2Mc9Yoh8z6hZInn3QwvMEYhHuQloYi+TTQy67SIdQ==", "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" } }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "node_modules/node-abi/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], "dependencies": { - "micromark-util-symbol": "^1.0.0" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "node_modules/node-abi/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/node-abi/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, - "node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true } - ] + } }, - "node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node_modules/node-polyfill-webpack-plugin": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-2.0.1.tgz", + "integrity": "sha512-ZUMiCnZkP1LF0Th2caY6J/eKKoA0TefpoVa68m/LQU1I/mE8rGt4fNYGgNuCcK+aG8P8P43nbeJ2RqJMOL/Y1A==", "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], "dependencies": { - "micromark-util-symbol": "^1.0.0" + "assert": "^2.0.0", + "browserify-zlib": "^0.2.0", + "buffer": "^6.0.3", + "console-browserify": "^1.2.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.12.0", + "domain-browser": "^4.22.0", + "events": "^3.3.0", + "filter-obj": "^2.0.2", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "^1.0.1", + "process": "^0.11.10", + "punycode": "^2.1.1", + "querystring-es3": "^0.2.1", + "readable-stream": "^4.0.0", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", + "string_decoder": "^1.3.0", + "timers-browserify": "^2.0.12", + "tty-browserify": "^0.0.1", + "type-fest": "^2.14.0", + "url": "^0.11.0", + "util": "^0.12.4", + "vm-browserify": "^1.1.2" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "webpack": ">=5" } }, - "node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^1.0.0" + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/micromark-util-subtokenize": { + "node_modules/normalize-svg-path": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz", + "integrity": "sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==", "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "svg-arc-to-cubic-bezier": "^3.0.0" } }, - "node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "path-key": "^3.0.0" }, "engines": { - "node": ">=8.6" + "node": ">=8" } }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "boolbase": "^1.0.0" }, - "bin": { - "miller-rabin": "bin/miller-rabin" + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true + "node_modules/nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "engines": { - "node": ">= 0.6" + "node": ">= 6" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mini-css-extract-plugin": { - "version": "2.7.6", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", - "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dependencies": { - "schema-utils": "^4.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">= 0.4" } }, - "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dependencies": { - "fast-deep-equal": "^3.1.3" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, - "peerDependencies": { - "ajv": "^8.8.2" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz", + "integrity": "sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==", "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "safe-array-concat": "^1.0.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 0.8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { + "node_modules/object.groupby": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, - "bin": { - "multicast-dns": "cli.js" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" }, - "node_modules/n3": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/n3/-/n3-1.17.2.tgz", - "integrity": "sha512-BxSM52wYFqXrbQQT5WUEzKUn6qpYV+2L4XZLfn3Gblz2kwZ09S+QxC33WNdVEQy2djenFL8SNkrjejEKlvI6+Q==", - "dev": true, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { - "queue-microtask": "^1.1.2", - "readable-stream": "^4.0.0" + "ee-first": "1.1.1" }, "engines": { - "node": ">=12.0" - } - }, - "node_modules/n8ao": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/n8ao/-/n8ao-1.6.8.tgz", - "integrity": "sha512-3xaBaoMIplgPdBK+9mZefa8stWEoA2673h2734wYMxm/hUkMLENMhzymDe+WZueFQq93ly4xpl5s1NJrQBzFOQ==", - "peerDependencies": { - "postprocessing": ">=6.30.0", - "three": ">=0.137" + "node": ">= 0.8" } }, - "node_modules/nan": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", - "dev": true - }, - "node_modules/napi-build-utils": { + "node_modules/on-headers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/node-abi": { - "version": "3.52.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.52.0.tgz", - "integrity": "sha512-JJ98b02z16ILv7859irtXn4oUaFWADtvkzy2c0IAatNVX2Mc9Yoh8z6hZInn3QwvMEYhHuQloYi+TTQy67SIdQ==", - "dev": true, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dependencies": { - "semver": "^7.3.5" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" }, "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/node-abi/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dependencies": { - "yallist": "^4.0.0" + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" }, "engines": { - "node": ">=10" + "node": ">= 0.8.0" } }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/node-abi/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dependencies": { - "whatwg-url": "^5.0.0" + "p-limit": "^3.0.2" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "engines": { - "node": ">= 6.13.0" + "node": ">=6" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, - "node_modules/node-polyfill-webpack-plugin": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-2.0.1.tgz", - "integrity": "sha512-ZUMiCnZkP1LF0Th2caY6J/eKKoA0TefpoVa68m/LQU1I/mE8rGt4fNYGgNuCcK+aG8P8P43nbeJ2RqJMOL/Y1A==", - "dev": true, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "dependencies": { - "assert": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^6.0.3", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.12.0", - "domain-browser": "^4.22.0", - "events": "^3.3.0", - "filter-obj": "^2.0.2", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^4.0.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.12", - "tty-browserify": "^0.0.1", - "type-fest": "^2.14.0", - "url": "^0.11.0", - "util": "^0.12.4", - "vm-browserify": "^1.1.2" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "webpack": ">=5" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" } }, - "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "engines": { - "node": ">=0.10.0" + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" } }, - "node_modules/normalize-svg-path": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz", - "integrity": "sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==", + "node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, "dependencies": { - "svg-arc-to-cubic-bezier": "^3.0.0" + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "node_modules/parse-entities/node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/normalize.css": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", - "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" + "node_modules/parse-svg-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", + "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==" + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" } }, - "node_modules/nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" } }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" }, "engines": { - "node": ">= 0.4" + "node": ">=0.12" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "engines": { - "node": ">= 0.4" + "node": ">=0.10.0" } }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 6" } }, - "node_modules/object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "find-up": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz", - "integrity": "sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==", + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dependencies": { - "array.prototype.reduce": "^1.0.6", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "safe-array-concat": "^1.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" + "node": ">=8" } }, - "node_modules/object.hasown": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", - "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dependencies": { - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "p-limit": "^2.2.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "dependencies": { - "ee-first": "1.1.1" + "find-up": "^3.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=6" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dependencies": { - "wrappy": "1" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "p-limit": "^2.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=6" } }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "p-limit": "^3.0.2" + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^10 || ^12 || >=14" } }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/postcss-attribute-case-insensitive": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", "dependencies": { - "yocto-queue": "^0.1.0" + "postcss-selector-parser": "^6.0.10" }, "engines": { - "node": ">=10" + "node": "^12 || ^14 || >=16" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/p-locate/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "node_modules/postcss-browser-comments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", "engines": { - "node": ">=10" + "node": ">=8" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "browserslist": ">=4", + "postcss": ">=8" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", "dependencies": { - "callsites": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, + "node_modules/postcss-color-hex-alpha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "dev": true, + "node_modules/postcss-color-rebeccapurple": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/parse-entities/node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/postcss-custom-media": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=8" + "node": "^12 || ^14 || >=16" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" } }, - "node_modules/parse-svg-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", - "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==" - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "node_modules/postcss-custom-properties": { + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">= 0.8" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "node_modules/postcss-custom-selectors": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" } }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, - "node_modules/path-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", - "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "node_modules/postcss-dir-pseudo-class": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", "engines": { - "node": ">=8" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", "engines": { - "node": ">=0.10.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", "engines": { - "node": ">=8" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", "engines": { - "node": ">=8" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/pbkdf2": { + "node_modules/postcss-double-position-gradients": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=0.12" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "node_modules/postcss-env-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "node_modules/postcss-flexbugs-fixes": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "peerDependencies": { + "postcss": "^8.1.4" + } }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/postcss-focus-visible": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, "engines": { - "node": ">=8.6" + "node": "^12 || ^14 || >=16" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "node_modules/postcss-focus-within": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, "engines": { - "node": ">=0.10.0" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "node_modules/postcss-gap-properties": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", "engines": { - "node": ">= 6" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", "dependencies": { - "find-up": "^4.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=8" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" }, "engines": { - "node": ">=8" + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" } }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", "dependencies": { - "p-locate": "^4.1.0" + "camelcase-css": "^2.0.1" }, "engines": { - "node": ">=8" + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" } }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", "dependencies": { - "p-try": "^2.0.0" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6" + "node": "^12 || ^14 || >=16" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", "dependencies": { - "p-limit": "^2.2.0" + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" }, "engines": { - "node": ">=8" + "node": ">= 14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", "engines": { - "node": ">=8" + "node": ">= 14" } }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/postcss-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", "dependencies": { - "locate-path": "^3.0.0" + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" }, "engines": { - "node": ">=6" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" } }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/postcss-loader/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/postcss-loader/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { - "p-try": "^2.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10" } }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/postcss-loader/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { - "p-limit": "^2.0.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } + "node_modules/postcss-loader/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "node_modules/postcss-logical": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "engines": { + "node": "^12 || ^14 || >=16" }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-media-minmax": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/postcss-attribute-case-insensitive": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", - "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", + "node_modules/postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" }, "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^8.2" + "postcss": "^8.2.15" } }, - "node_modules/postcss-browser-comments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "node_modules/postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, "engines": { - "node": ">=8" + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "browserslist": ">=4", - "postcss": ">=8" + "postcss": "^8.2.15" } }, - "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", "dependencies": { - "postcss-selector-parser": "^6.0.9", "postcss-value-parser": "^4.2.0" }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, "peerDependencies": { - "postcss": "^8.2.2" + "postcss": "^8.2.15" } }, - "node_modules/postcss-clamp": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", - "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=7.6.0" + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^8.4.6" + "postcss": "^8.2.15" } }, - "node_modules/postcss-color-functional-notation": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", - "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "node_modules/postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^8.2" + "postcss": "^8.2.15" } }, - "node_modules/postcss-color-hex-alpha": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", - "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", "dependencies": { - "postcss-value-parser": "^4.2.0" + "postcss-selector-parser": "^6.0.5" }, "engines": { - "node": "^12 || ^14 || >=16" + "node": "^10 || ^12 || >=14.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "engines": { + "node": "^10 || ^12 || >= 14" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.1.0" } }, - "node_modules/postcss-color-rebeccapurple": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", - "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", "dependencies": { - "postcss-value-parser": "^4.2.0" + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" }, "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "node": "^10 || ^12 || >= 14" }, "peerDependencies": { - "postcss": "^8.2" + "postcss": "^8.1.0" } }, - "node_modules/postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" + "postcss-selector-parser": "^6.0.4" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^10 || ^12 || >= 14" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.1.0" } }, - "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" + "icss-utils": "^5.0.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^10 || ^12 || >= 14" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.1.0" } }, - "node_modules/postcss-custom-media": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", - "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", "dependencies": { - "postcss-value-parser": "^4.2.0" + "postcss-selector-parser": "^6.0.11" }, "engines": { - "node": "^12 || ^14 || >=16" + "node": ">=12.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/csstools" + "url": "https://opencollective.com/postcss/" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2.14" } }, - "node_modules/postcss-custom-properties": { - "version": "12.1.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", - "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", + "node_modules/postcss-nesting": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", "dependencies": { - "postcss-value-parser": "^4.2.0" + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" }, "engines": { "node": "^12 || ^14 || >=16" @@ -14461,46 +18388,69 @@ "postcss": "^8.2" } }, - "node_modules/postcss-custom-selectors": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", - "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", + "node_modules/postcss-normalize": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", "dependencies": { - "postcss-selector-parser": "^6.0.4" + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" }, "engines": { - "node": "^12 || ^14 || >=16" + "node": ">= 12" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "peerDependencies": { + "browserslist": ">= 4", + "postcss": ">= 8" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "engines": { + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2.15" } }, - "node_modules/postcss-dir-pseudo-class": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", - "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^8.2" + "postcss": "^8.2.15" } }, - "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -14508,10 +18458,13 @@ "postcss": "^8.2.15" } }, - "node_modules/postcss-discard-duplicates": { + "node_modules/postcss-normalize-string": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -14519,10 +18472,13 @@ "postcss": "^8.2.15" } }, - "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -14530,10 +18486,14 @@ "postcss": "^8.2.15" } }, - "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "node_modules/postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -14541,87 +18501,104 @@ "postcss": "^8.2.15" } }, - "node_modules/postcss-double-position-gradients": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", - "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "normalize-url": "^6.0.1", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^8.2" + "postcss": "^8.2.15" } }, - "node_modules/postcss-env-function": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", - "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^12 || ^14 || >=16" + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2.15" } }, - "node_modules/postcss-flexbugs-fixes": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "node_modules/postcss-opacity-percentage": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "engines": { + "node": "^12 || ^14 || >=16" + }, "peerDependencies": { - "postcss": "^8.1.4" + "postcss": "^8.2" } }, - "node_modules/postcss-focus-visible": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", - "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "node_modules/postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", "dependencies": { - "postcss-selector-parser": "^6.0.9" + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^12 || ^14 || >=16" + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2.15" } }, - "node_modules/postcss-focus-within": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", - "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "node_modules/postcss-overflow-shorthand": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", "dependencies": { - "postcss-selector-parser": "^6.0.9" + "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^12 || ^14 || >=16" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, - "node_modules/postcss-font-variant": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", "peerDependencies": { - "postcss": "^8.1.0" + "postcss": "^8" } }, - "node_modules/postcss-gap-properties": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", - "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", + "node_modules/postcss-place": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { "node": "^12 || ^14 || >=16" }, @@ -14633,11 +18610,59 @@ "postcss": "^8.2" } }, - "node_modules/postcss-image-set-function": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", - "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "node_modules/postcss-preset-env": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", "dependencies": { + "@csstools/postcss-cascade-layers": "^1.1.1", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.1.0", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.10", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", "postcss-value-parser": "^4.2.0" }, "engines": { @@ -14651,55 +18676,67 @@ "postcss": "^8.2" } }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "node_modules/postcss-pseudo-class-any-link": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" + "postcss-selector-parser": "^6.0.10" }, "engines": { - "node": ">=14.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.0.0" + "postcss": "^8.2" } }, - "node_modules/postcss-initial": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "node_modules/postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, "peerDependencies": { - "postcss": "^8.0.0" + "postcss": "^8.2.15" } }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", "dependencies": { - "camelcase-css": "^2.0.1" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^8.4.21" + "postcss": "^8.2.15" } }, - "node_modules/postcss-lab-function": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", - "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" + "postcss-selector-parser": "^6.0.10" }, "engines": { "node": "^12 || ^14 || >=16" @@ -14712,1492 +18749,1476 @@ "postcss": "^8.2" } }, - "node_modules/postcss-load-config": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", - "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^2.1.1" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">= 14" + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "engines": { + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/postcss-svgo/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } + "engines": { + "node": ">=8.0.0" } }, - "node_modules/postcss-load-config/node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "node_modules/postcss-svgo/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/postcss-svgo/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { - "node": ">= 14" + "node": ">=0.10.0" } }, - "node_modules/postcss-loader": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", - "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", + "node_modules/postcss-svgo/node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", "dependencies": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.5", - "semver": "^7.3.5" + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" }, "engines": { - "node": ">= 12.13.0" + "node": ">=10.13.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "engines": { + "node": "^10 || ^12 || >=14.0" }, "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" + "postcss": "^8.2.15" } }, - "node_modules/postcss-loader/node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=10" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/postcss-loader/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/postprocessing": { + "version": "6.33.3", + "resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.33.3.tgz", + "integrity": "sha512-zQAVvcMf7bfeggQNQeVErD/UFd1XHBi2X6+yxwIv9PjhGCLAYKue3UuzVyu95O7ZUvkDwF0TyTzKdxoaVwYi7w==", + "engines": { + "node": ">= 0.13.2" + }, + "peerDependencies": { + "three": ">= 0.138.0 < 0.159.0" + } + }, + "node_modules/potpack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", + "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==" + }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dev": true, "dependencies": { - "yallist": "^4.0.0" + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" }, "engines": { "node": ">=10" } }, - "node_modules/postcss-loader/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "engines": { + "node": ">=6" }, - "bin": { - "semver": "bin/semver.js" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">=10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/postcss-loader/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/postcss-logical": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", - "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "engines": { - "node": "^12 || ^14 || >=16" + "node": ">=10" }, - "peerDependencies": { - "postcss": "^8.4" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/postcss-media-minmax": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", - "engines": { - "node": ">=10.0.0" + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/prism-react-renderer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.2.0.tgz", + "integrity": "sha512-j4AN0VkEr72598+47xDvpzeYyeh/wPPRNTt9nJFZqIZUxwGKwYqYgt7RVigZ3ZICJWJWN84KEuMKPNyypyhNIw==", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^1.2.1" }, "peerDependencies": { - "postcss": "^8.1.0" + "react": ">=16.0.0" } }, - "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">=6" } }, - "node_modules/postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">= 0.6.0" } }, - "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "asap": "~2.0.6" } }, - "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" }, "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">= 6" } }, - "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" } }, - "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "node_modules/property-information": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", + "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">= 0.10" } }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">= 0.10" } }, - "node_modules/postcss-modules-local-by-default": { + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/public-encrypt": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", - "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" } }, - "node_modules/postcss-modules-scope": { + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dependencies": { - "icss-utils": "^5.0.0" - }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">=6" } }, - "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.11" - }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.2.14" + "node": ">=0.6.0", + "teleport": ">=0.2.0" } }, - "node_modules/postcss-nesting": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", - "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dev": true, "dependencies": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" + "side-channel": "^1.0.4" }, "engines": { - "node": "^12 || ^14 || >=16" + "node": ">=0.6" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/postcss-normalize": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", - "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", - "dependencies": { - "@csstools/normalize.css": "*", - "postcss-browser-comments": "^4", - "sanitize.css": "*" - }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "browserslist": ">= 4", - "postcss": ">= 8" + "node": ">=0.4.x" } }, - "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, - "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "inherits": "~2.0.3" } }, - "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "performance-now": "^2.1.0" } }, - "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "safe-buffer": "^5.1.0" } }, - "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" } }, - "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">= 0.6" } }, - "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">= 0.8" } }, - "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">=0.10.0" } }, - "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, - "peerDependencies": { - "postcss": "^8.2.15" + "bin": { + "rc": "cli.js" } }, - "node_modules/postcss-opacity-percentage": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", - "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", - "funding": [ - { - "type": "kofi", - "url": "https://ko-fi.com/mrcgrtz" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/mrcgrtz" - } - ], + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.2" + "node": ">=0.10.0" } }, - "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "dependencies": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" + "loose-envify": "^1.1.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">=0.10.0" } }, - "node_modules/postcss-overflow-shorthand": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", - "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", + "node_modules/react-app-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", "dependencies": { - "postcss-value-parser": "^4.2.0" + "core-js": "^3.19.2", + "object-assign": "^4.1.1", + "promise": "^8.1.0", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" }, "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" + "node": ">=14" } }, - "node_modules/postcss-page-break": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "peerDependencies": { - "postcss": "^8" - } + "node_modules/react-app-polyfill/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, - "node_modules/postcss-place": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", - "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "node_modules/react-app-rewired": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-app-rewired/-/react-app-rewired-2.2.1.tgz", + "integrity": "sha512-uFQWTErXeLDrMzOJHKp0h8P1z0LV9HzPGsJ6adOtGlA/B9WfT6Shh4j2tLTTGlXOfiVx6w6iWpp7SOC5pvk+gA==", + "dev": true, "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" + "semver": "^5.6.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "bin": { + "react-app-rewired": "bin/index.js" }, "peerDependencies": { - "postcss": "^8.2" + "react-scripts": ">=2.1.3" } }, - "node_modules/postcss-preset-env": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", - "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", + "node_modules/react-composer": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/react-composer/-/react-composer-5.0.3.tgz", + "integrity": "sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA==", "dependencies": { - "@csstools/postcss-cascade-layers": "^1.1.1", - "@csstools/postcss-color-function": "^1.1.1", - "@csstools/postcss-font-format-keywords": "^1.0.1", - "@csstools/postcss-hwb-function": "^1.0.2", - "@csstools/postcss-ic-unit": "^1.0.1", - "@csstools/postcss-is-pseudo-class": "^2.0.7", - "@csstools/postcss-nested-calc": "^1.0.0", - "@csstools/postcss-normalize-display-values": "^1.0.1", - "@csstools/postcss-oklab-function": "^1.1.1", - "@csstools/postcss-progressive-custom-properties": "^1.3.0", - "@csstools/postcss-stepped-value-functions": "^1.0.1", - "@csstools/postcss-text-decoration-shorthand": "^1.0.0", - "@csstools/postcss-trigonometric-functions": "^1.0.2", - "@csstools/postcss-unset-value": "^1.0.2", - "autoprefixer": "^10.4.13", - "browserslist": "^4.21.4", - "css-blank-pseudo": "^3.0.3", - "css-has-pseudo": "^3.0.4", - "css-prefers-color-scheme": "^6.0.3", - "cssdb": "^7.1.0", - "postcss-attribute-case-insensitive": "^5.0.2", - "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^4.2.4", - "postcss-color-hex-alpha": "^8.0.4", - "postcss-color-rebeccapurple": "^7.1.1", - "postcss-custom-media": "^8.0.2", - "postcss-custom-properties": "^12.1.10", - "postcss-custom-selectors": "^6.0.3", - "postcss-dir-pseudo-class": "^6.0.5", - "postcss-double-position-gradients": "^3.1.2", - "postcss-env-function": "^4.0.6", - "postcss-focus-visible": "^6.0.4", - "postcss-focus-within": "^5.0.4", - "postcss-font-variant": "^5.0.0", - "postcss-gap-properties": "^3.0.5", - "postcss-image-set-function": "^4.0.7", - "postcss-initial": "^4.0.1", - "postcss-lab-function": "^4.2.1", - "postcss-logical": "^5.0.4", - "postcss-media-minmax": "^5.0.0", - "postcss-nesting": "^10.2.0", - "postcss-opacity-percentage": "^1.1.2", - "postcss-overflow-shorthand": "^3.0.4", - "postcss-page-break": "^3.0.4", - "postcss-place": "^7.0.5", - "postcss-pseudo-class-any-link": "^7.1.6", - "postcss-replace-overflow-wrap": "^4.0.0", - "postcss-selector-not": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "prop-types": "^15.6.0" }, "peerDependencies": { - "postcss": "^8.2" + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/postcss-pseudo-class-any-link": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", - "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" + "node": ">=14" } }, - "node_modules/postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "react": "^18.2.0" } }, - "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "node_modules/react-dom/node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" + "loose-envify": "^1.1.0" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "node_modules/react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "dependencies": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "react": ">=16.3.0" } }, - "node_modules/postcss-replace-overflow-wrap": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "node_modules/react-innertext": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/react-innertext/-/react-innertext-1.1.5.tgz", + "integrity": "sha512-PWAqdqhxhHIv80dT9znP2KvS+hfkbRovFp4zFYHFFlOoQLRiawIic81gKb3U1wEyJZgMwgs3JoLtwryASRWP3Q==", "peerDependencies": { - "postcss": "^8.0.3" + "@types/react": ">=0.0.0 <=99", + "react": ">=0.0.0 <=99" } }, - "node_modules/postcss-selector-not": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", - "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-merge-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz", + "integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" + "type": "github", + "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "node_modules/react-popper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", + "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17 || ^18", + "react-dom": "^16.8.0 || ^17 || ^18" } }, - "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "node_modules/react-reconciler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", + "integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==", "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" + "loose-envify": "^1.1.0", + "scheduler": "^0.21.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=0.10.0" }, "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" + "react": "^18.0.0" } }, - "node_modules/postcss-svgo/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "node_modules/react-reconciler/node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" + "loose-envify": "^1.1.0" } }, - "node_modules/postcss-svgo/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/postcss-svgo/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/react-refresh": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "engines": { "node": ">=0.10.0" } }, - "node_modules/postcss-svgo/node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "node_modules/react-router": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.19.0.tgz", + "integrity": "sha512-0W63PKCZ7+OuQd7Tm+RbkI8kCLmn4GPjDbX61tWljPxWgqTKlEpeQUwPkT1DRjYhF8KSihK0hQpmhU4uxVMcdw==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "@remix-run/router": "1.12.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=14.0.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "react": ">=16.8" } }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "node_modules/postcss/node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" + "node_modules/react-router-dom": { + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.19.0.tgz", + "integrity": "sha512-N6dWlcgL2w0U5HZUUqU2wlmOrSb3ighJmtQ438SWbhB1yuLTXQ8yyTBMK3BSvVjp7gBtKurT554nCtMOgxCZmQ==", + "dependencies": { + "@remix-run/router": "1.12.0", + "react-router": "6.19.0" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/postprocessing": { - "version": "6.33.3", - "resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.33.3.tgz", - "integrity": "sha512-zQAVvcMf7bfeggQNQeVErD/UFd1XHBi2X6+yxwIv9PjhGCLAYKue3UuzVyu95O7ZUvkDwF0TyTzKdxoaVwYi7w==", - "engines": { - "node": ">= 0.13.2" + "node": ">=14.0.0" }, "peerDependencies": { - "three": ">= 0.138.0 < 0.159.0" + "react": ">=16.8", + "react-dom": ">=16.8" } }, - "node_modules/potpack": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", - "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==" - }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "dev": true, + "node_modules/react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" }, "bin": { - "prebuild-install": "bin.js" + "react-scripts": "bin/react-scripts.js" }, "engines": { - "node": ">=10" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "engines": { - "node": ">=6" + "node": ">=14.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" + "optionalDependencies": { + "fsevents": "^2.3.2" + }, + "peerDependencies": { + "react": ">= 16", + "typescript": "^3.2.1 || ^4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/pretty-format": { + "node_modules/react-scripts/node_modules/@jest/console": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/react-scripts/node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": ">=10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/pretty-format/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "node_modules/prism-react-renderer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.2.0.tgz", - "integrity": "sha512-j4AN0VkEr72598+47xDvpzeYyeh/wPPRNTt9nJFZqIZUxwGKwYqYgt7RVigZ3ZICJWJWN84KEuMKPNyypyhNIw==", + "node_modules/react-scripts/node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", "dependencies": { - "@types/prismjs": "^1.26.0", - "clsx": "^1.2.1" + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" }, - "peerDependencies": { - "react": ">=16.0.0" - } - }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dependencies": { - "asap": "~2.0.6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "node_modules/react-scripts/node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/property-information": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", - "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "node_modules/react-scripts/node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" }, "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, + "node_modules/react-scripts/node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, "engines": { - "node": ">=6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "node_modules/react-scripts/node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dev": true, + "node_modules/react-scripts/node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", "dependencies": { - "side-channel": "^1.0.4" + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true, + "node_modules/react-scripts/node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, "engines": { - "node": ">=0.4.x" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "node_modules/react-scripts/node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dependencies": { - "inherits": "~2.0.3" + "type-detect": "4.0.8" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "node_modules/react-scripts/node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dependencies": { - "performance-now": "^2.1.0" + "@sinonjs/commons": "^1.7.0" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/react-scripts/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dependencies": { - "safe-buffer": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "node_modules/react-scripts/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/react-scripts/node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" + }, + "node_modules/react-scripts/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/react-scripts/node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "engines": { - "node": ">= 0.6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "node_modules/react-scripts/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" }, "engines": { - "node": ">= 0.8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/react-scripts/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, + "node_modules/react-scripts/node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" }, "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, + "jest": "bin/jest.js" + }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "node_modules/react-scripts/node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", "dependencies": { - "loose-envify": "^1.1.0" + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-app-polyfill": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", - "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", + "node_modules/react-scripts/node_modules/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", "dependencies": { - "core-js": "^3.19.2", - "object-assign": "^4.1.1", - "promise": "^8.1.0", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.9", - "whatwg-fetch": "^3.6.2" + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-app-polyfill/node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } }, - "node_modules/react-app-rewired": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-app-rewired/-/react-app-rewired-2.2.1.tgz", - "integrity": "sha512-uFQWTErXeLDrMzOJHKp0h8P1z0LV9HzPGsJ6adOtGlA/B9WfT6Shh4j2tLTTGlXOfiVx6w6iWpp7SOC5pvk+gA==", - "dev": true, + "node_modules/react-scripts/node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", "dependencies": { - "semver": "^5.6.0" + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" }, "bin": { - "react-app-rewired": "bin/index.js" + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { - "react-scripts": ">=2.1.3" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/react-composer": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/react-composer/-/react-composer-5.0.3.tgz", - "integrity": "sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA==", + "node_modules/react-scripts/node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", "dependencies": { - "prop-types": "^15.6.0" + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { - "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "node_modules/react-scripts/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dependencies": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">=14" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "node_modules/react-scripts/node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "detect-newline": "^3.0.0" }, - "peerDependencies": { - "react": "^18.2.0" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-dom/node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "node_modules/react-scripts/node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", "dependencies": { - "loose-envify": "^1.1.0" + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" - }, - "node_modules/react-helmet": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", - "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "node_modules/react-scripts/node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", "dependencies": { - "object-assign": "^4.1.1", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.1.1", - "react-side-effect": "^2.1.0" + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" }, - "peerDependencies": { - "react": ">=16.3.0" - } - }, - "node_modules/react-innertext": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/react-innertext/-/react-innertext-1.1.5.tgz", - "integrity": "sha512-PWAqdqhxhHIv80dT9znP2KvS+hfkbRovFp4zFYHFFlOoQLRiawIic81gKb3U1wEyJZgMwgs3JoLtwryASRWP3Q==", - "peerDependencies": { - "@types/react": ">=0.0.0 <=99", - "react": ">=0.0.0 <=99" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/react-merge-refs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz", - "integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node_modules/react-scripts/node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-popper": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", - "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", + "node_modules/react-scripts/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dependencies": { - "react-fast-compare": "^3.0.1", - "warning": "^4.0.2" + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, - "peerDependencies": { - "@popperjs/core": "^2.0.0", - "react": "^16.8.0 || ^17 || ^18", - "react-dom": "^16.8.0 || ^17 || ^18" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-reconciler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", - "integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==", + "node_modules/react-scripts/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.21.0" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "react": "^18.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-reconciler/node_modules/scheduler": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", - "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "node_modules/react-scripts/node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", "dependencies": { - "loose-envify": "^1.1.0" + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-refresh": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", - "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "node_modules/react-scripts/node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-router": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.19.0.tgz", - "integrity": "sha512-0W63PKCZ7+OuQd7Tm+RbkI8kCLmn4GPjDbX61tWljPxWgqTKlEpeQUwPkT1DRjYhF8KSihK0hQpmhU4uxVMcdw==", + "node_modules/react-scripts/node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", "dependencies": { - "@remix-run/router": "1.12.0" + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" }, "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-router-dom": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.19.0.tgz", - "integrity": "sha512-N6dWlcgL2w0U5HZUUqU2wlmOrSb3ighJmtQ438SWbhB1yuLTXQ8yyTBMK3BSvVjp7gBtKurT554nCtMOgxCZmQ==", + "node_modules/react-scripts/node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", "dependencies": { - "@remix-run/router": "1.12.0", - "react-router": "6.19.0" + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-scripts": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", - "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "node_modules/react-scripts/node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", "dependencies": { - "@babel/core": "^7.16.0", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", - "@svgr/webpack": "^5.5.0", - "babel-jest": "^27.4.2", - "babel-loader": "^8.2.3", - "babel-plugin-named-asset-import": "^0.3.8", - "babel-preset-react-app": "^10.0.1", - "bfj": "^7.0.2", - "browserslist": "^4.18.1", - "camelcase": "^6.2.1", - "case-sensitive-paths-webpack-plugin": "^2.4.0", - "css-loader": "^6.5.1", - "css-minimizer-webpack-plugin": "^3.2.0", - "dotenv": "^10.0.0", - "dotenv-expand": "^5.1.0", - "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.1", - "eslint-webpack-plugin": "^3.1.1", - "file-loader": "^6.2.0", - "fs-extra": "^10.0.0", - "html-webpack-plugin": "^5.5.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^27.4.3", - "jest-resolve": "^27.4.2", - "jest-watch-typeahead": "^1.0.0", - "mini-css-extract-plugin": "^2.4.5", - "postcss": "^8.4.4", - "postcss-flexbugs-fixes": "^5.0.2", - "postcss-loader": "^6.2.1", - "postcss-normalize": "^10.0.1", - "postcss-preset-env": "^7.0.1", - "prompts": "^2.4.2", - "react-app-polyfill": "^3.0.0", - "react-dev-utils": "^12.0.1", - "react-refresh": "^0.11.0", - "resolve": "^1.20.0", - "resolve-url-loader": "^4.0.0", - "sass-loader": "^12.3.0", - "semver": "^7.3.5", - "source-map-loader": "^3.0.0", - "style-loader": "^3.3.1", - "tailwindcss": "^3.0.2", - "terser-webpack-plugin": "^5.2.5", - "webpack": "^5.64.4", - "webpack-dev-server": "^4.6.0", - "webpack-manifest-plugin": "^4.0.2", - "workbox-webpack-plugin": "^6.4.1" - }, - "bin": { - "react-scripts": "bin/react-scripts.js" + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" }, "engines": { - "node": ">=14.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - }, - "peerDependencies": { - "react": ">= 16", - "typescript": "^3.2.1 || ^4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-scripts/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "node_modules/react-scripts/node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" }, "engines": { - "node": ">=12" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/react-scripts/node_modules/lru-cache": { @@ -16225,11 +20246,65 @@ "node": ">=10" } }, - "node_modules/react-scripts/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, + "node_modules/react-scripts/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-scripts/node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/react-scripts/node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/react-scripts/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/react-scripts/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/react-scripts/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, "node_modules/react-side-effect": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz", @@ -17858,6 +21933,14 @@ "node": ">=10" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -18281,17 +22364,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tempy/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tempy/node_modules/type-fest": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", @@ -18640,6 +22712,210 @@ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, + "node_modules/ts-jest": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", + "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/ts-jest/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/ts-jest/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/ts-jest/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/ts-jest/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/ts-jest/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", + "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -19240,24 +23516,26 @@ "node": ">=6" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "convert-source-map": "^2.0.0" }, "engines": { "node": ">=10.12.0" } }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -19630,85 +23908,11 @@ "node": ">= 10" } }, - "node_modules/webpack-dev-server/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/webpack-dev-server/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/webpack-dev-server/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, - "node_modules/webpack-dev-server/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-dev-server/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/webpack-dev-server/node_modules/p-retry": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", @@ -19739,14 +23943,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/webpack-dev-server/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, "node_modules/webpack-manifest-plugin": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", @@ -20359,28 +24555,50 @@ } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/zustand": { diff --git a/package.json b/package.json index c3f43cf..f2c9c7a 100755 --- a/package.json +++ b/package.json @@ -31,12 +31,14 @@ }, "devDependencies": { "@react-pdf/types": "^2.3.1", + "@types/jest": "^29.5.11", "@types/lodash": "^4.14.194", "@types/node": "^20.1.0", "@types/prismjs": "^1.26.0", "@types/react": "^18.2.6", "@types/react-dom": "^18.2.4", "@types/react-helmet": "^6.1.7", + "jest": "^29.7.0", "node-polyfill-webpack-plugin": "^2.0.1", "react-app-rewired": "^2.2.1", "react-dev-utils": "^12.0.1", @@ -45,6 +47,8 @@ "tree-sitter": "^0.20.6", "tree-sitter-python": "^0.20.4", "tree-sitter-typescript": "^0.20.3", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.2", "typescript": "^5.0.4" }, "scripts": { @@ -53,6 +57,10 @@ "test": "react-app-rewired test", "eject": "react-app-rewired eject" }, + "jest": { + "testMatch": ["**/*.spec.ts"], + "testPathIgnorePatterns": [",./external"] + }, "eslintConfig": { "extends": [ "react-app", diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts new file mode 100644 index 0000000..1c21494 --- /dev/null +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -0,0 +1,142 @@ +import {Ray, RayType} from "./Ray"; +import {PreventsImplementationBug} from "./errors/errors"; + +describe("Ray", () => { + test(".empty", () => { + /** [ ] */ + const ray = Ray.empty(); + + expect(ray.self.is_none()).toBe(true); + expect(ray.self.is_some()).toBe(false); + expect(ray.self.initial.is_none()).toBe(true); + expect(ray.self.vertex.is_none()).toBe(true); + expect(ray.self.terminal.is_none()).toBe(true); + + expect(ray.is_none()).toBe(true); + expect(ray.is_some()).toBe(false); + + expect(ray.is_initial()).toBe(false); + expect(ray.is_vertex()).toBe(true); + expect(ray.is_terminal()).toBe(false); + expect(ray.is_reference()).toBe(false); + expect(ray.type).toBe(RayType.VERTEX); + + }); + test(".empty.#", () => { + /** + * [ | ] + * | + * [?????] + */ + + const ray = Ray.empty().as_reference(); + + expect(ray.self.is_none()).toBe(true); + expect(ray.self.is_some()).toBe(false); + expect(ray.self.initial.is_none()).toBe(true); + expect(ray.self.vertex.is_none()).toBe(true); + expect(ray.self.terminal.is_none()).toBe(true); + + expect(ray.is_none()).toBe(true); + expect(ray.is_some()).toBe(false); + + expect(ray.is_initial()).toBe(false); + expect(ray.is_vertex()).toBe(true); + expect(ray.is_terminal()).toBe(false); + expect(ray.is_reference()).toBe(false); + expect(ray.type).toBe(RayType.VERTEX); + + }); + test(".empty.#.#", () => { + /** + * [ | ] + * | + * [ | ] + * | + * [?????] + */ + const ray = Ray.empty().as_reference().as_reference(); + + expect(ray.self.is_none()).toBe(true); + expect(ray.self.is_some()).toBe(false); + + expect(ray.self.initial.is_none()).toBe(true); + expect(ray.self.vertex.is_none()).toBe(true); + expect(ray.self.terminal.is_none()).toBe(true); + + expect(ray.is_none()).toBe(false); + expect(ray.is_some()).toBe(true); + + expect(ray.is_initial()).toBe(true); + expect(ray.is_vertex()).toBe(false); + expect(ray.is_terminal()).toBe(true); + expect(ray.is_reference()).toBe(true); + expect(ray.type).toBe(RayType.REFERENCE); + }); + test(".empty.#.#.#", () => { + /** + * ... + * | + * [ | ] + * | + * [ | ] + * | + * [ | ] + * | + * [?????] + */ + let ray = Ray.empty().as_reference().as_reference().as_reference(); + + expect(ray.self.is_none()).toBe(false); + expect(ray.self.is_some()).toBe(true); + expect(ray.self.initial.is_none()).toBe(true); + expect(ray.self.vertex.is_none()).toBe(true); + expect(ray.self.terminal.is_none()).toBe(true); + + expect(ray.is_none()).toBe(false); + expect(ray.is_some()).toBe(true); + + expect(ray.is_initial()).toBe(true); + expect(ray.is_vertex()).toBe(false); + expect(ray.is_terminal()).toBe(true); + expect(ray.is_reference()).toBe(true); + expect(ray.type).toBe(RayType.REFERENCE); + }); + test(".empty.#.#.#.#[4-15]", () => { + /** + * Basically the empty value is out of scope of our direct drill, and we expect this behavior 'infinitely' up the reference stack. + * ... + * [ | ] <-- ray + * | + * [ | ] <-- ray.self - (ray.self.is_none()) + * | + * [ | ] <-- ray.self.self - (ray.self.self === ray.self.self.self) + * | + * [ | ] <-- ray.self.self.self - = false + * | + * [?????] + */ + for (let i = 4; i <= 15; i++) { + let ray = Ray.empty(); + for (let j = 0; j < i; j++) { + ray = ray.as_reference(); + } + + expect(ray.self.is_none()).toBe(false); + expect(ray.self.is_some()).toBe(true); + expect(ray.self.initial.is_none()).toBe(true); + expect(ray.self.vertex.is_none()).toBe(false); + expect(ray.self.terminal.is_none()).toBe(true); + + expect(ray.is_none()).toBe(false); + expect(ray.is_some()).toBe(true); + + expect(ray.is_initial()).toBe(true); + expect(ray.is_vertex()).toBe(false); + expect(ray.is_terminal()).toBe(true); + expect(ray.is_reference()).toBe(true); + expect(ray.type).toBe(RayType.REFERENCE); + } + }); +}); + diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index d7cfcdd..5526c0e 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,9 +1,10 @@ import _ from "lodash"; -import {NotImplementedError} from "./errors/errors"; +import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; // SHOULDNT CLASSIFY THESE? export enum RayType { + NONE = ' ', REFERENCE = ' | ', INITIAL = ' |-?', TERMINAL = '?-| ', @@ -63,15 +64,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? protected _terminal: Arbitrary; get terminal(): Ray { return this._terminal(); } set terminal(terminal: Arbitrary) { this._terminal = terminal; } get self(): Ray { - if (!this.is_reference()) - throw new NotImplementedError('Preventing bugs, .self is used for the assumption of a reference..'); - + // if (!this.vertex.is_none()) + // throw new PreventsImplementationBug('Preventing bugs, .self is used for the assumption of a reference..'); + // return this.vertex; }; set self(self: Arbitrary) { - if (!this.is_reference()) - throw new NotImplementedError('Preventing bugs, .self is used for the assumption of a reference..'); - + // if (!this.is_reference()) + // throw new PreventsImplementationBug('Preventing bugs, .self is used for the assumption of a reference..'); + // this.vertex = self; } @@ -81,21 +82,21 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? js, }: { js?: Arbitrary } & Partial> = {}) { this._initial = initial ?? Ray.None; - this._vertex = vertex ?? Ray.None; + this._vertex = vertex ?? this.self_reference; this._terminal = terminal ?? Ray.None; this.js = js ?? Ray.None; } - /** [ |-?] */ is_initial = (): boolean => this.self.is_some() && this.self.initial.is_none(); + /** [ |-?] */ is_initial = (): boolean => this.is_some() && this.self.initial.is_none(); /** [--|--] */ is_vertex = (): boolean => !this.is_initial() && !this.is_terminal(); - /** [?-| ] */ is_terminal = (): boolean => this.self.is_some() && this.self.terminal.is_none(); + /** [?-| ] */ is_terminal = (): boolean => this.is_some() && this.self.terminal.is_none(); /** [ | ] */ is_reference = (): boolean => this.is_initial() && this.is_terminal(); - /** [?- -?] */ is_empty = (): boolean => this.self.is_none(); get type(): RayType { /** [ | ] */ if (this.is_reference()) return RayType.REFERENCE; /** [ |-?] */ if (this.is_initial()) return RayType.INITIAL; /** [?-| ] */ if (this.is_terminal()) return RayType.TERMINAL; + // /** [ ] */ if (this.is_empty()) return RayType.NONE; /** [--|--] */ return RayType.VERTEX; } @@ -114,7 +115,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. */ - is_none = (): boolean => this.self === this; + is_none = (): boolean => this.self === this.self.self; + + protected self_reference = () => this; /** [ ] */ static None = (): Ray => { const self = Ray.empty(); // TODO: None, could also self-reference the ray on which it's defining to be None. Now it's just an ignorant loop. diff --git a/src/@orbitmines/explorer/errors/errors.ts b/src/@orbitmines/explorer/errors/errors.ts index 55688dc..963386f 100644 --- a/src/@orbitmines/explorer/errors/errors.ts +++ b/src/@orbitmines/explorer/errors/errors.ts @@ -1 +1,2 @@ export class NotImplementedError extends Error {} +export class PreventsImplementationBug extends Error {} diff --git a/src/@orbitmines/external/implementations/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts similarity index 100% rename from src/@orbitmines/external/implementations/chyp/Chyp.ts rename to src/@orbitmines/external/chyp/Chyp.ts diff --git a/src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx similarity index 100% rename from src/@orbitmines/external/implementations/chyp/ChypCanvas.tsx rename to src/@orbitmines/external/chyp/ChypCanvas.tsx diff --git a/src/@orbitmines/external/github.com/akissinger/chyp b/src/@orbitmines/external/github.com/akissinger/chyp deleted file mode 160000 index da4161c..0000000 --- a/src/@orbitmines/external/github.com/akissinger/chyp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit da4161c3145270f7d5f54138930d3e50a66028fc From 7a5f1d79158486989b3c4fed622fdfa7415f331a Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 13:06:50 +0100 Subject: [PATCH 022/138] 2024/02/09 - Rename empty to None --- src/@orbitmines/explorer/Ray.spec.ts | 20 ++++++++++---------- src/@orbitmines/explorer/Ray.ts | 14 ++++---------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 1c21494..8ff38ce 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -2,9 +2,9 @@ import {Ray, RayType} from "./Ray"; import {PreventsImplementationBug} from "./errors/errors"; describe("Ray", () => { - test(".empty", () => { + test(".None", () => { /** [ ] */ - const ray = Ray.empty(); + const ray = Ray.None(); expect(ray.self.is_none()).toBe(true); expect(ray.self.is_some()).toBe(false); @@ -22,14 +22,14 @@ describe("Ray", () => { expect(ray.type).toBe(RayType.VERTEX); }); - test(".empty.#", () => { + test(".None.#", () => { /** * [ | ] * | * [?????] */ - const ray = Ray.empty().as_reference(); + const ray = Ray.None().as_reference(); expect(ray.self.is_none()).toBe(true); expect(ray.self.is_some()).toBe(false); @@ -47,7 +47,7 @@ describe("Ray", () => { expect(ray.type).toBe(RayType.VERTEX); }); - test(".empty.#.#", () => { + test(".None.#.#", () => { /** * [ | ] * | @@ -55,7 +55,7 @@ describe("Ray", () => { * | * [?????] */ - const ray = Ray.empty().as_reference().as_reference(); + const ray = Ray.None().as_reference().as_reference(); expect(ray.self.is_none()).toBe(true); expect(ray.self.is_some()).toBe(false); @@ -73,7 +73,7 @@ describe("Ray", () => { expect(ray.is_reference()).toBe(true); expect(ray.type).toBe(RayType.REFERENCE); }); - test(".empty.#.#.#", () => { + test(".None.#.#.#", () => { /** * ... * | @@ -85,7 +85,7 @@ describe("Ray", () => { * | * [?????] */ - let ray = Ray.empty().as_reference().as_reference().as_reference(); + let ray = Ray.None().as_reference().as_reference().as_reference(); expect(ray.self.is_none()).toBe(false); expect(ray.self.is_some()).toBe(true); @@ -102,7 +102,7 @@ describe("Ray", () => { expect(ray.is_reference()).toBe(true); expect(ray.type).toBe(RayType.REFERENCE); }); - test(".empty.#.#.#.#[4-15]", () => { + test(".None.#.#.#.#[4-15]", () => { /** * Basically the empty value is out of scope of our direct drill, and we expect this behavior 'infinitely' up the reference stack. * ... @@ -117,7 +117,7 @@ describe("Ray", () => { * [?????] */ for (let i = 4; i <= 15; i++) { - let ray = Ray.empty(); + let ray = Ray.None(); for (let j = 0; j < i; j++) { ray = ray.as_reference(); } diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 5526c0e..922ef67 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -82,7 +82,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? js, }: { js?: Arbitrary } & Partial> = {}) { this._initial = initial ?? Ray.None; - this._vertex = vertex ?? this.self_reference; + this._vertex = vertex ?? this.self_reference; // TODO: None, could also self-reference the ray on which it's defining to be None. Now it's just an ignorant loop. this._terminal = terminal ?? Ray.None; this.js = js ?? Ray.None; } @@ -101,7 +101,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } /** - * This is basically what breaks the recursive nature of this structure. Imagine a Ray like this: [|--|--|]. There are several ways of interpreting it, either there's a boolean on initial, vertex, terminal; Some 'false' value, says there's nothing there. Some true value says there's something there. - Basically an Option, ..., Maybe as in certain languages. + * This is basically what breaks the recursive structure. Imagine a Ray like this: [|--|--|]. There are several ways of interpreting it, either there's a boolean on initial, vertex, terminal; Some 'false' value, says there's nothing there. Some true value says there's something there. - Basically an Option, ..., Maybe as in certain languages. * * --- * @@ -119,17 +119,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? protected self_reference = () => this; - /** [ ] */ static None = (): Ray => { - const self = Ray.empty(); // TODO: None, could also self-reference the ray on which it's defining to be None. Now it's just an ignorant loop. - self.self = () => self; - return self; - } - is_some = (): boolean => !this.is_none(); - /** [ ] */ static empty = () => new Ray({ }); + /** [ ] */ static None = () => new Ray({ }); /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { - /** [ ] */ const vertex = Ray.empty(); + /** [ ] */ const vertex = Ray.None(); /** [-- ] */ vertex.initial = vertex.as_initial; /** [ ? ] */ vertex.vertex = value; /** [ --] */ vertex.terminal = vertex.as_terminal; From 395a62109e698a2ab337f4a57a768bc8f4cb6eb6 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 13:53:01 +0100 Subject: [PATCH 023/138] 2024/02/09 - Vertex tests --- src/@orbitmines/explorer/Ray.spec.ts | 57 ++++++++++++++++++++++++++++ src/@orbitmines/explorer/Ray.ts | 11 +++--- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 8ff38ce..e60a497 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -2,6 +2,63 @@ import {Ray, RayType} from "./Ray"; import {PreventsImplementationBug} from "./errors/errors"; describe("Ray", () => { + test(".vertex.#", () => { + /** [--|--] */ const vertex = Ray.vertex().as_reference(); + + expect(vertex.type).toBe(RayType.VERTEX); + + expect(vertex.is_none()).toBe(false); + expect(vertex.is_some()).toBe(true); + + expect(vertex.is_initial()).toBe(false); + expect(vertex.is_vertex()).toBe(true); + expect(vertex.is_terminal()).toBe(false); + expect(vertex.is_reference()).toBe(false); + }); + test(".vertex.initial.#", () => { + /** [--|--] */ const vertex = Ray.vertex(); + /** [ |--] */ const initial = vertex.initial.as_reference(); + + expect(initial.self.initial.is_none()).toBe(true); + expect(initial.self).not.toBe(initial.self.self); // If self-referential, that means none. + + expect(initial.self.terminal).toBe(vertex); + expect(initial.self.terminal.self).not.toBe(vertex); + + expect(initial.self.is_none()).toBe(false); + expect(initial.self.self.is_none()).toBe(true); + + expect(initial.is_some()).toBe(true); + expect(initial.self.terminal.is_none()).toBe(false); + + expect(initial.is_initial()).toBe(true); + expect(initial.is_vertex()).toBe(false); + expect(initial.is_terminal()).toBe(false); + expect(initial.is_reference()).toBe(false); + expect(initial.type).toBe(RayType.INITIAL); + }); + test(".vertex.terminal.#", () => { + /** [--|--] */ const vertex = Ray.vertex(); + /** [ |--] */ const terminal = vertex.terminal.as_reference(); + + expect(terminal.self.terminal.is_none()).toBe(true); + expect(terminal.self).not.toBe(terminal.self.self); // If self-referential, that means none. + + expect(terminal.self.initial).toBe(vertex); + expect(terminal.self.initial.self).not.toBe(vertex); + + expect(terminal.self.is_none()).toBe(false); + expect(terminal.self.self.is_none()).toBe(true); + + expect(terminal.is_some()).toBe(true); + expect(terminal.self.initial.is_none()).toBe(false); + + expect(terminal.is_terminal()).toBe(true); + expect(terminal.is_vertex()).toBe(false); + expect(terminal.is_initial()).toBe(false); + expect(terminal.is_reference()).toBe(false); + expect(terminal.type).toBe(RayType.TERMINAL); + }); test(".None", () => { /** [ ] */ const ray = Ray.None(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 922ef67..328b15d 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -123,10 +123,14 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** [ ] */ static None = () => new Ray({ }); /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { + // /** [?????] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }); + // /** [?????] -> [??? ] */ as_terminal = () => + // new Ray({ initial: this.as_arbitrary(), vertex: () => this.terminal, js: () => 'terminal ref' }); // TODO: These fields as DEBUG + /** [ ] */ const vertex = Ray.None(); - /** [-- ] */ vertex.initial = vertex.as_initial; + /** [-- ] */ vertex.initial = new Ray({ vertex: Ray.None, terminal: vertex.as_arbitrary(), js: () => 'initial ref' }).as_arbitrary(); /** [ ? ] */ vertex.vertex = value; - /** [ --] */ vertex.terminal = vertex.as_terminal; + /** [ --] */ vertex.terminal = new Ray({ vertex: Ray.None, initial: vertex.as_arbitrary(), js: () => 'terminal ref' }).as_arbitrary() /** [--?--] */ return vertex; } @@ -143,9 +147,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); - /** [?????] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }); - /** [?????] -> [??? ] */ as_terminal = () => - new Ray({ initial: this.as_arbitrary(), vertex: () => this.terminal, js: () => 'terminal ref' }); // TODO: These fields as DEBUG // as_option = (): Ray => Option.Some(this); as_arbitrary = (): Arbitrary => () => this; From d91eaaf927106ea45be5371cb5562609ce6c7e10 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 14:11:37 +0100 Subject: [PATCH 024/138] 2024/02/09 - continues_with is compose --- src/@orbitmines/explorer/Ray.ts | 84 ++++++++++++++------------------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 328b15d..61dc11a 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -4,7 +4,7 @@ import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; // SHOULDNT CLASSIFY THESE? export enum RayType { - NONE = ' ', + // NONE = ' ', REFERENCE = ' | ', INITIAL = ' |-?', TERMINAL = '?-| ', @@ -151,59 +151,47 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // as_option = (): Ray => Option.Some(this); as_arbitrary = (): Arbitrary => () => this; + continues_with = (b: Ray): Ray => { + // TODO: contiues_with is just composing vertices.. - continues_with = (continues_with: Ray): Ray => { - if (!this.as_reference().is_reference()) - throw 'NotImplemented: Preventing implementation bug; continues_with not called on a reference'; - if (!continues_with.as_reference().is_reference()) - throw 'NotImplemented: Preventing implementation bug; continues_with not called with a reference'; - - if (!continues_with.is_reference()) - throw 'NotImplemented: Preventing implementation bug; continues_with not called as a reference'; - - // TODO: For now just puts it at the vertex, could be done more intelligently - const next_vertex = Ray.vertex(() => continues_with.vertex); - - const vertex = this.self; - - if (vertex.is_empty()) { - console.log('first element') - this.vertex = next_vertex.as_arbitrary(); - return this; - } - - if (!this.is_vertex()) - throw 'NotImplemented: Preventing implementation bug; continues_with not called on a vertex'; - - if (!vertex.terminal.is_empty()) - throw 'NotImplemented: Preventing implementation bug; continues_with should be added to the vertex'; - - // [ |--] - const next_connection = vertex.as_terminal(); - - // console.log(initial_connection.label) - vertex.terminal = next_connection.as_arbitrary(); + switch (this.type) { + case RayType.REFERENCE: { + // TODO: We could either go inside the reference and continue there, or expand the direction of reference + // TODO: We could move when a reference is on the vertex, set the type to vertex from the perspective of the reference + throw new PreventsImplementationBug(); + } + case RayType.TERMINAL: + case RayType.INITIAL: { + // TODO: Could be each element found in this direction, or continue *after* the entire direction + throw new PreventsImplementationBug(); + } + case RayType.VERTEX: { + const next_vertex = Ray.vertex(b.as_arbitrary()); // TODO: Could be a reference too, now just force as a next element - const previous_connection = next_vertex.as_initial(); + if (this.is_none()) { + // 'Empty' vertex from this perspective. - next_vertex.initial = previous_connection.as_arbitrary(); + this.vertex = next_vertex.as_arbitrary(); + console.log('first element'); + return next_vertex.as_reference(); // TODO: Generally, return something which knows where all continuations are. + } - next_connection.vertex = previous_connection.as_arbitrary(); - previous_connection.vertex = next_connection.as_arbitrary(); + // this.self.terminal = next_vertex.initial; equivalence# - // next_vertex.initial = connection.vertex.force().as_arbitrary(); + // switch (b.type) { + // case RayType.REFERENCE: + // break; + // case RayType.INITIAL: + // break; + // case RayType.TERMINAL: + // break; + // case RayType.VERTEX: + // break; + // } - // const connection = new Ray({ - // vertex: this.as_arbitrary(), - // terminal: next_vertex.as_arbitrary() - // }).as_arbitrary(); - // - // this.terminal = connection; - // next_vertex.initial = connection; - // - // console.log('continues') - - return next_vertex.as_reference(); + return next_vertex.as_reference(); + } + } } // TODO NEEDS TO CHECK IF THERE'S SOME INITIAL DEFIEND ; for defining if it has halted From f53b531794afef3d695f37ea6a25cf4653d014a0 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 14:38:16 +0100 Subject: [PATCH 025/138] 2024/02/09 - ChypCanvas merge changes --- .../explorer/OrbitMinesExplorer.tsx | 82 ++- src/@orbitmines/explorer/Ray.spec.ts | 2 + src/@orbitmines/explorer/Ray.ts | 33 +- src/@orbitmines/external/chyp/Chyp.ts | 6 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 21 +- src/App.tsx | 2 +- src/routes/papers/2023.OnOrbits.tsx | 474 +++++++++--------- 7 files changed, 307 insertions(+), 313 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index 2dfe2a8..9e2f135 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -1,18 +1,16 @@ -import React, {useEffect, useMemo, useRef, useState} from 'react'; -import {empty, empty_vertex, from_boolean, from_iterable, JS, Ray, RayType} from "./Ray"; +import React, {useEffect, useRef, useState} from 'react'; +import {Ray, RayType} from "./Ray"; import {VisualizationCanvas} from "./Visualization"; -import {CatmullRomLine, Circle, CubicBezierLine, QuadraticBezierLine, Text, Torus} from "@react-three/drei"; -import {GroupProps, useFrame, useThree,} from "@react-three/fiber"; +import {CatmullRomLine, Circle, CubicBezierLine, QuadraticBezierLine, Torus} from "@react-three/drei"; +import {useFrame, useThree,} from "@react-three/fiber"; import {useDrag} from "@use-gesture/react"; import {useSpring} from '@react-spring/three' import {useHotkeys} from "../js/react/hooks/useHotkeys"; -import JetBrainsMonoRegular from "../../lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Regular.ttf"; -import {Box3, SplineCurve, TorusGeometry, Vector3, WebGLRenderTarget} from "three"; -import {Option} from "../js/utils/Option"; +import {WebGLRenderTarget} from "three"; import _ from "lodash"; import IEventListener, {mergeListeners} from "../js/react/IEventListener"; -import {toJpeg, toPng} from "html-to-image"; -import {Children, value} from "../../lib/typescript/React"; +import {toPng} from "html-to-image"; +import {Children} from "../../lib/typescript/React"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import {NotImplementedError} from "./errors/errors"; @@ -322,10 +320,10 @@ export const RenderedRay = ( const left = initial; const right = terminal; - if (reference.is_none() || reference.force().self().is_none()) + if (reference.is_none() || reference.is_none()) return <> - const vertex = reference.force().self().force(); + const vertex = reference.self; const Rendered = () => { @@ -339,17 +337,17 @@ export const RenderedRay = ( if (vertex.vertex.is_none()) { return } else { - const possible_continuations = vertex.vertex.force(); + const possible_continuations = vertex.vertex; if (!possible_continuations.as_reference().is_terminal()) return // - // if (vertex.terminal.force().store.rendered) + // if (vertex.terminal.store.rendered) // return <> return } } @@ -357,7 +355,7 @@ export const RenderedRay = ( if (vertex.vertex.is_none()) { return } else { - const possible_continuations = vertex.vertex.force(); + const possible_continuations = vertex.vertex; // if (!possible_continuations.as_reference().is_initial()) // return @@ -365,16 +363,16 @@ export const RenderedRay = ( // return } } case RayType.REFERENCE: { - if (vertex.is_empty()) // empty reference + if (vertex.as_reference().is_none()) // empty reference return // throw 'Not Implemented' - return ray.as_reference(), None: () => Ray.None })} /> + return } case RayType.VERTEX: { const tilt = -10; // TODO; Generally should use some equivalencing in the 3d-frames for this once setup is in place (perpsective/camera) if in threejs.. @@ -404,14 +402,14 @@ export const RenderedRay = ( // const right = add(position, [20, 0, 0]); // // return <> - // + // // // {/* Line now starts in the center of the torus tube */} // // {/**/} // // - // + // // // } @@ -544,8 +542,8 @@ export const RenderedRay = ( {/**/} {/**/} - {/**/} - + {/**/} + {/* Line now starts in the center of the torus tube */} {/*{isVertical*/} @@ -569,7 +567,7 @@ export const RenderedRay = ( {/*{<>*/} - {/* */} + {/* */} {/* /!* Line now starts in the center of the torus tube *!/*/} {/* */} @@ -583,11 +581,11 @@ export const RenderedRay = ( {/* : */} {/* }*/} - {/* */} + {/* */} {/*}*/} - + {/*(); const [selection, setSelection] = useState( - empty_vertex().as_reference() + Ray.vertex().as_reference() ); const [controls, setControls] = useState( - empty().as_reference() + Ray.vertex().as_reference() ); const { @@ -699,8 +697,8 @@ const InterfaceObject = ({ } }, { combo: "arrowright", global: true, label: "", onKeyDown: () => { - const next = selection.force().continues_with( - new Ray({ js: () => Option.Some("A") }).as_reference() + const next = selection.continues_with( + Ray.js("A").as_reference() ); setSelection(next) @@ -713,7 +711,7 @@ const InterfaceObject = ({ } useEffect(() => { - console.log(selection.force().to_wolfram_language()) + console.log(selection.to_wolfram_language()) }, [selection]); useEffect(() => { @@ -891,7 +889,7 @@ const Test2 = ({ ray, position }: { ray: Ray, position: [number, number, number] {[...ray.traverse()].map((vertex, i) => ( - + ))} ) @@ -904,7 +902,7 @@ const Test2 = ({ ray, position }: { ray: Ray, position: [number, number, number] // useEffect(() => { -// for (let vertex of ray.force().traverse()) { +// for (let vertex of ray.traverse()) { // /** // * In this case should be a reference and thus // * [--|--] @@ -914,11 +912,11 @@ const Test2 = ({ ray, position }: { ray: Ray, position: [number, number, number] // const reference = vertex.vertex; // // if (reference.is_some()) { -// if (reference.force().vertex.is_none()) +// if (reference.vertex.is_none()) // continue; // // // This would be the Iterator, or the numbers respectively. -// const dereferenced = reference.force().vertex.force(); +// const dereferenced = reference.vertex; // /** // * Can again be any of these: // * [--|--] @@ -927,21 +925,21 @@ const Test2 = ({ ray, position }: { ray: Ray, position: [number, number, number] // * // */ // -// console.log('type:', reference.force().type); -// console.log('structure at', dereferenced.js().force()) +// console.log('type:', reference.type); +// console.log('structure at', dereferenced.js()) // // console.log(' traversing nested reference'); -// for (let nested of reference.force().traverse()) { +// for (let nested of reference.traverse()) { // const nested_reference = nested.vertex; // // if (nested_reference.is_some()) { -// if (nested_reference.force().vertex.is_none()) +// if (nested_reference.vertex.is_none()) // continue; // -// const nested_dereferenced = nested_reference.force().vertex.force(); +// const nested_dereferenced = nested_reference.vertex; // -// console.log('type:', nested_reference.force().toString()); -// console.log('structure at', nested_dereferenced.js().force()) +// console.log('type:', nested_reference.toString()); +// console.log('structure at', nested_dereferenced.js()) // } // } // console.log(' done'); @@ -957,7 +955,7 @@ const OrbitMinesExplorer = ( } ) => { // const ray = JS.Iterable([14, 15, [[6, 7, 8, 9, 10, 11], 100], 1, 2, 3, 4, 5, 16, false]).as_ray(); - // console.log(ray.force().to_wolfram_language()) + // console.log(ray.to_wolfram_language()) // visualization_config // hotkey/interface_config diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index e60a497..6ace225 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -24,6 +24,7 @@ describe("Ray", () => { expect(initial.self.terminal).toBe(vertex); expect(initial.self.terminal.self).not.toBe(vertex); + expect(initial.self.terminal.initial).toBe(initial.self); expect(initial.self.is_none()).toBe(false); expect(initial.self.self.is_none()).toBe(true); @@ -46,6 +47,7 @@ describe("Ray", () => { expect(terminal.self.initial).toBe(vertex); expect(terminal.self.initial.self).not.toBe(vertex); + expect(terminal.self.initial.terminal).toBe(terminal.self); expect(terminal.self.is_none()).toBe(false); expect(terminal.self.self.is_none()).toBe(true); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 80c530a..2aa26fe 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,10 +1,6 @@ import _ from "lodash"; -import {compile} from "sass"; -import {NotImplementedError} from "./errors/errors"; -import {InterfaceOptions} from "./OrbitMinesExplorer"; - -export type ParameterlessFunction = () => T; import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; +import {InterfaceOptions} from "./OrbitMinesExplorer"; // SHOULDNT CLASSIFY THESE? @@ -210,7 +206,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? copy = (): Ray => { throw new NotImplementedError() } // export const at = (index: number, of: number, value: any = undefined): Arbitrary> => { -// return Arbitrary.Fn(() => length(of, value).resolve().force().at_terminal(index)); +// return Arbitrary.Fn(() => length(of, value).resolve().at_terminal(index)); // } // at = (steps: number | Ray | Arbitrary): Ray => { throw new NotImplementedError(); } @@ -230,9 +226,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? cast = (): T => { throw new NotImplementedError(); }; // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' - map = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } - all = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } - filter = (mapping: (ray: Ray) => Ray | JS | any): Ray => { throw new NotImplementedError(); } + map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + all = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } clear = (): Ray => { throw new NotImplementedError(); } // TODO: Generalize these functions to: @@ -302,10 +298,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? get store(): any { return Ray.dirty_store[this.label] ??= {} } o = (o: InterfaceOptions): Ray => { return this.with('options', o); } - get o_(): InterfaceOptions { return this.store['options'] ?? { - - } - } + get o_(): InterfaceOptions { return this.store['options'] ?? {} } with = (key: string, any: any): Ray => { this.store[key] = any; @@ -464,10 +457,10 @@ export namespace JS { const terminal = new Ray({ initial: () => initial }); - // initial.force().continues_with(() => terminal.as_reference()); + // initial.continues_with(() => terminal.as_reference()); // if (initial.is_some()) - // initial.force().terminal = () => terminal; // TODO REPEAT FROM BELOW + // initial.terminal = () => terminal; // TODO REPEAT FROM BELOW return terminal; } @@ -476,18 +469,18 @@ export namespace JS { js: () => iterator_result.value, // initial: () => new Ray(), initial: () => initial, - vertex: () => from_any(iterator_result.value).as_ray(), + vertex: () => JS.Any(iterator_result.value), terminal: () => next(current) }); - // initial.force().continues_with(() => current.force().as_reference()); + // initial.continues_with(() => current.as_reference()); if (initial.is_some()) initial.terminal = () => current; return current; } - const ray_iterator = new Ray({ js: () => Option.Some(iterator)}); + const ray_iterator = new Ray({ js: () => iterator}); ray_iterator.terminal = () => next(ray_iterator); // This indicates we're passing a reference, since traversal logic will be defined at its vertex - what it's defining. @@ -521,7 +514,9 @@ export namespace JS { if (JS.is_function(any)) return JS.Function(any); if (JS.is_object(any)) return JS.Object(any); - return JS.Any(any); + // TODO + // return JS.Any(any); + return Ray.js(any); } export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index 96f1859..a7272cd 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -173,8 +173,8 @@ export class VData extends Ray { merge = (other: VData): Ray => { // TODO: other is destroyed // TODO: Vertices - // this.initial.force().equivalent(other.initial.force()); - // this.terminal.force().equivalent(other.initial.force()); + // this.initial.equivalent(other.initial); + // this.terminal.equivalent(other.initial); /* @@ -1220,7 +1220,7 @@ export class Rule extends Ray { */ is_left_linear = (): Ray => { // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading - return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray().force() + return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. } diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 1fab79d..1e664d7 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -1,11 +1,10 @@ import React, {useRef, useState} from "react"; -import IEventListener, {mergeListeners} from "../../../js/react/IEventListener"; -import {VisualizationCanvas} from "../../../explorer/Visualization"; -import {add, AutoRenderedRay, BinarySuperposition, Loop, SimpleRenderedRay} from "../../../explorer/OrbitMinesExplorer"; -import {empty_vertex, js, Ray, RayType} from "../../../explorer/Ray"; +import IEventListener from "../../js/react/IEventListener"; +import {VisualizationCanvas} from "../../explorer/Visualization"; +import {add, AutoRenderedRay} from "../../explorer/OrbitMinesExplorer"; import {Center} from "@react-three/drei"; -import {Option} from "../../../js/utils/Option"; -import {useHotkeys} from "../../../js/react/hooks/useHotkeys"; +import {useHotkeys} from "../../js/react/hooks/useHotkeys"; +import {Ray} from "../../explorer/Ray"; const Interface = () => { const ref = useRef(); @@ -15,7 +14,7 @@ const Interface = () => { const i = 20 * scale; const [selection, setSelection] = useState( - empty_vertex().as_reference().o({ + Ray.vertex().as_reference().o({ position: [0, 0, 0], scale }) @@ -27,7 +26,7 @@ const Interface = () => { { combo: "arrowright", global: true, label: "", onKeyDown: () => { - const next = js("A").as_reference().o({ + const next = Ray.js("A").as_reference().o({ position: add(selection.o_.position ?? [0, 0, 0], [i * 2, 0, 0]), scale }); @@ -59,16 +58,16 @@ const Interface = () => { setRays(rays.flatMap(ray => [ ray, - js("A").as_reference().o({ + Ray.js("A").as_reference().o({ ...ray.o_, position: add(ray.o_.position ?? [0, 0, 0], [0, i * 2, 0]) }), - js("A").as_reference().o({ + Ray.js("A").as_reference().o({ ...ray.o_, position: ray.o_.position, rotation: [0, 0, Math.PI / 2] }), - js("A").as_reference().o({ + Ray.js("A").as_reference().o({ ...ray.o_, position: add(ray.o_.position ?? [0, 0, 0], [0, i * 2, 0]), rotation: [0, 0, Math.PI / 2] diff --git a/src/App.tsx b/src/App.tsx index c0b5463..d88a9ef 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,7 +13,7 @@ import BlueprintJS from "./lib/layout/experimental-designs/BlueprintJS"; import Modules from "./@orbitmines/js/react/Modules"; import Icons from "./lib/layout/experimental-designs/Icons"; import {ThumbnailPage} from "./lib/paper/Paper"; -import ChypCanvas, {ChypExplorer} from "./@orbitmines/external/implementations/chyp/ChypCanvas"; +import {ChypExplorer} from "./@orbitmines/external/chyp/ChypCanvas"; export const Router = () => { diff --git a/src/routes/papers/2023.OnOrbits.tsx b/src/routes/papers/2023.OnOrbits.tsx index 70af93a..c37d6b1 100644 --- a/src/routes/papers/2023.OnOrbits.tsx +++ b/src/routes/papers/2023.OnOrbits.tsx @@ -23,7 +23,7 @@ import { RenderedRay, torus, Vertex } from "../../@orbitmines/explorer/OrbitMinesExplorer"; -import {length} from "../../@orbitmines/explorer/Ray"; +import {Ray} from "../../@orbitmines/explorer/Ray"; import {HorizontalLine} from "../../lib/paper/PaperContent"; import CustomIcon from "../../lib/layout/icons/CustomIcon"; import REFERENCES from "../../profiles/FadiShawki/FadiShawki"; @@ -106,16 +106,16 @@ const OnOrbits = () => { - - - + @@ -137,7 +137,7 @@ const OnOrbits = () => { - @@ -182,7 +182,7 @@ const OnOrbits = () => { - + @@ -212,7 +212,7 @@ const OnOrbits = () => { - + @@ -230,7 +230,7 @@ const OnOrbits = () => {
- +
@@ -249,9 +249,9 @@ const OnOrbits = () => {
- - +
@@ -267,9 +267,9 @@ const OnOrbits = () => {
- - +
@@ -286,9 +286,9 @@ const OnOrbits = () => {
- - +
@@ -304,16 +304,16 @@ const OnOrbits = () => {
- - - - + @@ -337,28 +337,28 @@ const OnOrbits = () => {
- - + - + - - + - + @@ -376,26 +376,26 @@ const OnOrbits = () => {
- - - - + - - - + @@ -413,12 +413,12 @@ const OnOrbits = () => {
- - + - @@ -441,21 +441,21 @@ const OnOrbits = () => {
- - - - - - + @@ -475,13 +475,13 @@ const OnOrbits = () => {
- - - @@ -509,9 +509,9 @@ const OnOrbits = () => {
- - +
@@ -527,12 +527,12 @@ const OnOrbits = () => {
- + - - +
@@ -548,12 +548,12 @@ const OnOrbits = () => {
- + - - +
@@ -577,7 +577,7 @@ const OnOrbits = () => {
- +
@@ -593,12 +593,12 @@ const OnOrbits = () => {
- + - - +
@@ -635,22 +635,22 @@ const OnOrbits = () => {
- + - - + - + - - + @@ -676,12 +676,12 @@ const OnOrbits = () => {
- + - - +
@@ -709,15 +709,15 @@ const OnOrbits = () => {
- + - - + - @@ -740,10 +740,10 @@ const OnOrbits = () => {
- + - +
@@ -757,7 +757,7 @@ const OnOrbits = () => { - + @@ -772,10 +772,10 @@ const OnOrbits = () => {
- + - +
@@ -796,22 +796,22 @@ const OnOrbits = () => {
- + - - + - + - - + @@ -836,21 +836,21 @@ const OnOrbits = () => { - - + - - + - +
@@ -864,7 +864,7 @@ const OnOrbits = () => {
- +
@@ -881,12 +881,12 @@ const OnOrbits = () => {
- + - - +
@@ -905,33 +905,33 @@ const OnOrbits = () => {
- - - + + + - - - + + + - - + - - + - - +
@@ -970,7 +970,7 @@ const OnOrbits = () => { - + @@ -984,9 +984,9 @@ const OnOrbits = () => {
- - + @@ -1040,12 +1040,12 @@ const OnOrbits = () => { - {/**/} + {/**/} - - + @@ -1082,22 +1082,22 @@ const OnOrbits = () => { - {/**/} + {/**/} - - + - {/**/} + {/**/} - - + @@ -1122,12 +1122,12 @@ const OnOrbits = () => { - {/**/} + {/**/} - - + @@ -1162,9 +1162,9 @@ const OnOrbits = () => {
- - +
@@ -1207,9 +1207,9 @@ const OnOrbits = () => { - - +
@@ -1268,9 +1268,9 @@ const OnOrbits = () => {
- - +
@@ -1288,21 +1288,21 @@ const OnOrbits = () => {
- - - - - + -
@@ -1318,12 +1318,12 @@ const OnOrbits = () => {
- + - - +
@@ -1341,14 +1341,14 @@ const OnOrbits = () => {
- - - +
@@ -1367,21 +1367,21 @@ const OnOrbits = () => {
- - + - - - +
@@ -1400,52 +1400,52 @@ const OnOrbits = () => {
- - + - - + - - + - - + - - + - - - +
@@ -1465,24 +1465,24 @@ const OnOrbits = () => { - + - - {/**/} - - @@ -1503,32 +1503,32 @@ const OnOrbits = () => { - + - - {/**/} - - - +
@@ -1584,24 +1584,24 @@ const OnOrbits = () => { - + - - {/**/} - - @@ -1619,9 +1619,9 @@ const OnOrbits = () => {
- - +
@@ -1637,14 +1637,14 @@ const OnOrbits = () => {
- - - +
@@ -1677,30 +1677,30 @@ const OnOrbits = () => {
- + - - {/**/} - - - +
@@ -1719,34 +1719,34 @@ const OnOrbits = () => { - - + + - - + + - + - - + + - - + + - - - + + @@ -1756,29 +1756,29 @@ const OnOrbits = () => { - + - + - - {/**/} - - @@ -1800,34 +1800,34 @@ const OnOrbits = () => { - - + + - - + + - + - - + + - - + + - - - + + @@ -1837,29 +1837,29 @@ const OnOrbits = () => { - + - + - - {/**/} - - @@ -1879,30 +1879,30 @@ const OnOrbits = () => {
- + - - {/**/} - - - +
@@ -1926,10 +1926,10 @@ const OnOrbits = () => {
- - - - + + + +
@@ -1945,7 +1945,7 @@ const OnOrbits = () => {
- @@ -1967,10 +1967,10 @@ const OnOrbits = () => {
- - - - + + + +
@@ -1987,28 +1987,28 @@ const OnOrbits = () => {
- - + + - - - - + + - - From ad43623cc4e28d3f699ddc63fad1237367d5c884 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 16:11:55 +0100 Subject: [PATCH 026/138] 2024/02/09 - Experimenting with some react rendering ideas, need something better for this --- .../explorer/OrbitMinesExplorer.tsx | 120 +- src/@orbitmines/explorer/Ray.ts | 175 +- src/@orbitmines/external/chyp/Chyp.ts | 2728 ++++++++--------- src/@orbitmines/external/chyp/ChypCanvas.tsx | 25 +- src/lib/paper/Paper.tsx | 12 +- src/lib/paper/PaperContent.tsx | 8 +- 6 files changed, 1657 insertions(+), 1411 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index 9e2f135..c1776e0 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -1,5 +1,5 @@ import React, {useEffect, useRef, useState} from 'react'; -import {Ray, RayType} from "./Ray"; +import {AbstractDirectionality, Ray, RayType} from "./Ray"; import {VisualizationCanvas} from "./Visualization"; import {CatmullRomLine, Circle, CubicBezierLine, QuadraticBezierLine, Torus} from "@react-three/drei"; import {useFrame, useThree,} from "@react-three/fiber"; @@ -211,7 +211,96 @@ type Options = { terminal?: InterfaceOptions, } -export const AutoRenderedRay = (ray: Omit & InterfaceOptions & { +type RenderContext = Compiler; // Rendering is Compiling - Something which holds equivalences and ignores/shuts down self-referential structures. +export type Compiler = { + coverage(ray: Ray): Ray, // Disallow dedups + covered_by(cover: Ray, ray: Ray): Compiler +} + +class TempCompiler implements Compiler { + coverage(ray: Ray): Ray { + return Ray.None(); + } + covered_by(cover: Ray, ray: Ray): Compiler { + return this; + } +} + +export const AutoRay = ( + { ray, + compiler, + initial: _default_initial, + terminal: _default_terminal, + ...options + }: { ray: Ray, compiler?: Compiler } & Omit & InterfaceOptions +) => { + compiler ??= new TempCompiler(); + + const o = (ray: Ray, defaults: InterfaceOptions = {}): Required => ({ + position: [0, 0, 0], + rotation: [0, 0, 0], + scale: 1.5, + color: 'orange', + ...defaults, + ...ray.o_ + }); + + // Move to a layer of abstraction above what is passed to us - this way we can start describing it. + const ref = { // TODO; This general pattern is probably worth abstracting somewhere. + initial: ray.initial.as_reference(), + vertex: ray.as_reference(), + terminal: ray.terminal.as_reference() + } + + if (compiler.coverage(ray).is_some()) + return <>; + + // console.log(ref.vertex.type) + + compiler.covered_by(ref.vertex, ray); + + const interface_options = { // TODO: See here again + initial: o(ray.initial, { ..._default_initial }), + vertex: o(ray, { ...options }), + terminal: o(ray.terminal, { ..._default_terminal }), + } + + // + // switch (ref.vertex.type) { + // case RayType.REFERENCE: + // break; + // case RayType.INITIAL: + // break; + // case RayType.TERMINAL: + // break; + // case RayType.VERTEX: + // break; + // } + // + + // const _default = { scale: 1.5 } + // // + // const map: { [type: string]: { [type: string]: Pick & InterfaceOptions }} = { + // [RayType.INITIAL]: { + // [RayType.INITIAL]: { type: RayType.INITIAL, position: [-20 * _default.scale, 0, 0] }, + // [RayType.VERTEX]: { type: RayType.VERTEX, position: [-20 * _default.scale, 0, 0], rotation: [0, 0, Math.PI / 2] }, + // [RayType.TERMINAL]: { type: RayType.TERMINAL }, + // } + // } + // const initial_op = map[RayType.INITIAL][ref.initial.type]; + + return + {/*{ref.initial.is_none() ? : }*/} + + {/**/} + +} + +export const AutoVertex = (ray: Omit & InterfaceOptions & { length?: number // basically .length children?: any }) => { @@ -237,7 +326,7 @@ export const AutoRenderedRay = (ray: Omit & InterfaceOptions if (length > 1) // TODO, currently rotates around each vertex individually return {[...Array(length)] - .map(((_, i) => ))} + .map(((_, i) => ))} const Group = ({ children }: Children) => { return @@ -253,6 +342,18 @@ export const AutoRenderedRay = (ray: Omit & InterfaceOptions {children} } +const _Continuation = ({ color = torus.color, ...options }: InterfaceOptions) => + +const _Vertex = ({ color = circle.color, ...options }: any) => + export const SimpleRenderedRay = ( ray: Pick & Options // Relative options to other rays @@ -266,19 +367,6 @@ export const SimpleRenderedRay = ( ..._.pick(ray, 'position', 'rotation', 'scale', 'color') } - const _Continuation = ({ color = torus.color, ...options }: InterfaceOptions) => - - const _Vertex = ({ color = circle.color, ...options }: any) => - - const initial: Required = { ..._default, ...ray.initial }; const vertex: Required = { ..._default, ...ray.vertex }; const terminal: Required = { ..._default, ...ray.terminal }; diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 2aa26fe..4d36162 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,6 +1,9 @@ -import _ from "lodash"; +import _, {initial} from "lodash"; import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; +import {value} from "../../lib/typescript/React"; +import {current} from "../../profiles/FadiShawki/FadiShawki2"; +import {debug} from "node:util"; // SHOULDNT CLASSIFY THESE? @@ -51,8 +54,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? PossiblyHomoiconic, AsyncIterable, - Iterable, - Array + Iterable//, + // Array // Dict { @@ -149,6 +152,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); + // as_option = (): Ray => Option.Some(this); as_arbitrary = (): Arbitrary => () => this; @@ -226,9 +230,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? cast = (): T => { throw new NotImplementedError(); }; // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' - map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + // map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } all = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } - filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + // filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } clear = (): Ray => { throw new NotImplementedError(); } // TODO: Generalize these functions to: @@ -297,10 +301,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? static dirty_store: { [label: string]: object } = {} get store(): any { return Ray.dirty_store[this.label] ??= {} } - o = (o: InterfaceOptions): Ray => { return this.with('options', o); } + // TODO: This is just any object implementation, nest the objects into a separte field, + o = (o: InterfaceOptions): Ray => { return this.___with('options', o); } get o_(): InterfaceOptions { return this.store['options'] ?? {} } - with = (key: string, any: any): Ray => { + ___with = (key: string, any: any): Ray => { this.store[key] = any; return this; } @@ -397,6 +402,162 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return this.__label = `"${Ray._label++} (${this.js()?.toString() ?? '?'})})"`; } + // length: number; + // + // concat(...items: ConcatArray[]): Ray[]; + // concat(...items: (ConcatArray | Ray)[]): Ray[]; + // concat(...items: (ConcatArray | Ray)[]): Ray[] { + // return []; + // } + // + // copyWithin(target: number, start: number, end?: number): this { + // return undefined; + // } + // + // entries(): IterableIterator<[number, Ray]> { + // return undefined; + // } + // + // every(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): this is S[]; + // every(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean; + // every(predicate, thisArg?: any): any { + // } + // + // fill(value: Ray, start?: number, end?: number): this { + // return undefined; + // } + // + // filter(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S[]; + // filter(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray[]; + // filter(predicate, thisArg?: any): any { + // } + // + // find(predicate: (value: Ray, index: number, obj: Ray[]) => value is S, thisArg?: any): S | undefined; + // find(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // find(predicate, thisArg?: any): any { + // } + // + // findIndex(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): number { + // return 0; + // } + // + // forEach(callbackfn: (value: Ray, index: number, array: Ray[]) => void, thisArg?: any): void { + // } + // + // indexOf(searchElement: Ray, fromIndex?: number): number { + // return 0; + // } + // + // join(separator?: string): string { + // return ""; + // } + // + // keys(): IterableIterator { + // return undefined; + // } + // + // lastIndexOf(searchElement: Ray, fromIndex?: number): number { + // return 0; + // } + // + // map(callbackfn: (value: Ray, index: number, array: Ray[]) => U, thisArg?: any): U[] { + // return []; + // } + // + // pop(): Ray | undefined { + // return undefined; + // } + // + // push(...items: Ray[]): number { + // return 0; + // } + // + // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; + // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; + // reduce(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduce(callbackfn, initialValue?): any { + // } + // + // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; + // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; + // reduceRight(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduceRight(callbackfn, initialValue?): any { + // } + // + // reverse(): Ray[] { + // return []; + // } + // + // shift(): Ray | undefined { + // return undefined; + // } + // + // slice(start?: number, end?: number): Ray[] { + // return []; + // } + // + // some(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean { + // return false; + // } + // + // sort(compareFn?: (a: Ray, b: Ray) => number): this { + // return undefined; + // } + // + // splice(start: number, deleteCount?: number): Ray[]; + // splice(start: number, deleteCount: number, ...items: Ray[]): Ray[]; + // splice(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // return []; + // } + // + // unshift(...items: Ray[]): number { + // return 0; + // } + // + // values(): IterableIterator { + // return undefined; + // } + // + // findLast(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S | undefined; + // findLast(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // findLast(predicate, thisArg?: any): any { + // } + // + // findLastIndex(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): number { + // return 0; + // } + // + // flat(depth?: D): FlatArray[] { + // return []; + // } + // + // flatMap(callback: (this: This, value: Ray, index: number, array: Ray[]) => (ReadonlyArray | U), thisArg?: This): U[] { + // return []; + // } + // + // includes(searchElement: Ray, fromIndex?: number): boolean { + // return false; + // } + // + // toReversed(): Ray[] { + // return []; + // } + // + // toSorted(compareFn?: (a: Ray, b: Ray) => number): Ray[] { + // return []; + // } + // + // toSpliced(start: number, deleteCount: number, ...items: Ray[]): Ray[]; + // toSpliced(start: number, deleteCount?: number): Ray[]; + // toSpliced(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // return []; + // } + // + // with(index: number, value: Ray): Ray[] { + // return []; + // } + + } // force = (): any => self.match({ // Some: (a) => a, diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index a7272cd..c4a9633 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1,1364 +1,1364 @@ -import {Arbitrary, empty, JS, Ray} from "../../../explorer/Ray"; -import { NotImplementedError } from "../../../explorer/errors/errors"; -import {Option} from "../../../js/utils/Option"; - -/** - * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. - * GitHub: https://github.com/akissinger/chyp - * - * A simple way of phrasing this conversion, is that the concept of a 'Vertex', 'Edge', 'Graph', 'Rule', ..., 'Rewrite' are merged into one thing: a Ray. - * - * NOTE: - * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. - * - * - The .copy()'s are implemented on Ray. - * - * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. - * - * TODO: Probably want all these types at runtime, to display them - * - * TODO: Graph boundary is automatic with this structure? - * - * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? - * - * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. - * - * TODO: Can just move the terminal which holds the oointer to the boundary - * - * TODO: Automatically generate visual examples of all the methods - * - * TODO: Runtime errors as rays - * - * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph - */ - -export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; - -export class ValueError extends Error {} - -/** - * Non-default vertex types are identified by a string label - * - * str() | None() - No overloading in TypeScript ;( - */ -export const VType = JS.Iterable([str, None]); - -/** - * An error occurred in the graph backend. - * - * TODO probably hooked as a boolean, one successful the other not - */ -export class GraphError extends Error {} -export class RuleError extends Error {} - -/** - * Used for debugging (the matcher) - */ -const DEBUG = true; // TODO; Generalize -const log = (s: string) => { - if (!DEBUG) - return; - - console.log(s); -} - -/** - * Data associated with a single vertex. - */ -export class VData extends Ray { - - // The vertex type. - get vtype(): Ray { throw new NotImplementedError(); } - - /** - * The register size (number of bundled parallel wires) of the vertex. - * - * TODO: Just a counter over a line - */ - get size(): Ray { throw new NotImplementedError(); } - - /** - * Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). - */ - get infer_type(): Ray { throw new NotImplementedError(); } - - /** - * Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). - */ - get infer_size(): Ray { throw new NotImplementedError(); } - - - /** - * TODO: These coordinates used for inferences? - * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" - */ - - // x-coordinate at which to draw the vertex. - get x(): Ray { throw new NotImplementedError(); } - // y-coordinate at which to draw the vertex. - get y(): Ray { throw new NotImplementedError(); } - - // TODO: Just some boolean - get highlight(): Ray { throw new NotImplementedError(); } - - get value(): Ray { throw new NotImplementedError(); } - - /** - * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. - * - * TODO ; // set[int] = set() - * TODO ; these are just the initial/terminal sides of a Ray. they're just duplicated - */ - get in_edges(): Ray { throw new NotImplementedError(); } - get out_edges(): Ray { throw new NotImplementedError(); } - - /** - * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. - */ - get in_indices(): Ray { return this.initial } // - get out_indices(): Ray { throw new NotImplementedError(); } - - /** - * Initialize a VData instance. - */ - __init__ = (): Ray => { - this.highlight = bool(False); - this.in_edges = set(int); - this.out_edges = set(int); - this.in_indices = set(int); - this.out_indices = set(int); - } - - - is_input = (): Ray => this.in_indices.count() > 0; - is_output = (): Ray => this.out_indices.count() > 0; - is_boundary = (): Ray => this.is_input() || this.is_output(); - - // TODO: Probably generalizable - - /** - * - * @param other - */ - merge = (other: VData): Ray => { - // TODO: other is destroyed - // TODO: Vertices - // this.initial.equivalent(other.initial); - // this.terminal.equivalent(other.initial); - - /* - - vd = self.vertex_data(v) - # print("merging %s <- %s" % (v, w)) - - # Where vertex `w` occurs as an edge target, replace it with `v` - for e in self.in_edges(w): - ed = self.edge_data(e) - ed.t = [v if x == w else x for x in ed.t] - vd.in_edges.add(e) - - # Where vertex `w` occurs as an edge source, replace it with `v` - for e in self.out_edges(w): - ed = self.edge_data(e) - ed.s = [v if x == w else x for x in ed.s] - vd.out_edges.add(e) - - # Wherever `w` occurs on the graph boundary, replace it with `v` - self.set_inputs([v if x == w else x for x in self.inputs()]) - self.set_outputs([v if x == w else x for x in self.outputs()]) - - # Remove references to `w` from the graph - self.remove_vertex(w) - - */ - - throw new NotImplementedError(); - } - - fresh = (): VData => { - // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. - - // vtype=vd.vtype, size=vd.size, - // x=vd.x, y=vd.y, value=vd.value - - } -} - -/** - * Data associated with a single edge. - */ -export class EData extends Ray { - - // TODO: this is just the initial frame - get s(): Ray { throw new NotImplementedError(); } - - // TODO: this is just the terminal frame - get t(): Ray { throw new NotImplementedError(); } - - - get x(): Ray { throw new NotImplementedError(); } - get y(): Ray { throw new NotImplementedError(); } - get fg(): Ray { throw new NotImplementedError(); } - get bg(): Ray { throw new NotImplementedError(); } - get highlight(): Ray { throw new NotImplementedError(); } - get hyper(): Ray { throw new NotImplementedError(); } - get value(): Ray { throw new NotImplementedError(); } - - __init__ = (): Ray => { - this.s = empty(); - this.t = empty(); - this.highlight = bool(False); - } - - __repr__ = (): Ray => { throw new NotImplementedError(); - // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' - } - - // TODO: More stuff to relate it to the screen that shouldnt be here. - /** - * Return how many width 'units' this box needs to display nicely. - * - * This uses a simple rule: - * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. - * - Otherwise draw as a larger (size 2) box. - */ - box_size = (): Ray => (this.s.count() <= 1 && this.t.count() <= 1) ? 1 : 2; - - toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL - - get source() { return this.s }; - get target() { return this.t }; - - // TODO: Shouldn't be here, this should either be implemented on Ray if it's general enough, of just remain here as an artifact - protected ___domain = (ray: Ray) => ray.map(_ => { - const vertex: VData = _.cast(); - return [vertex.vtype, vertex.size]; - }); - - domain = (): Ray => this.___domain(this.source); - codomain = (): Ray => this.___domain(this.target); - -} - -/** - * A hypergraph with boundaries. - * - * This is the main data structure used by Chyp. It represents a directed - * hypergraph (which we call simply a "graph") as two dictionaries for - * vertices and (hyper)edges, respectively. Each vertex is associated with a - * `VData` object and edge edge with an `EData` object, which stores - * information about adjacency, position, label, etc. - * - * The particular flavor of hypergraphs we use associate to each hyperedge a - * list of source vertices and a list of target vertices. The hypergraph - * itself also has a list of input vertices and a list of output vertices, - * which are used for sequential composition and rewriting. - */ -export class Graph extends Ray { - - // Mapping from integer identifiers of each vertex to its data. - get vdata(): Ray { throw new NotImplementedError(); } - // Mapping from integer identifiers of each hyperedge to its data. - get edata(): Ray { throw new NotImplementedError(); } - - // TODO: Can probably generate these on the fly, or cache them automatically - get vindex(): Ray { return this.vdata.index.max(0); } - get eindex(): Ray { return this.edata.index.max(0); } - - // TODO .keys - vertices = (): Ray => this.vdata; - edges = (): Ray => this.edata; - - // TODO: Shouldn't be here, this should either be implemented on Ray if it's general enough, of just remain here as an artifact - protected ___domain = (ray: Ray) => ray.map(_ => { - const vertex: VData = _.cast(); - return [vertex.vtype, vertex.size]; - }); - - /** - * Return the domain of the graph. - * - * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. - */ - // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. - get domain(): Ray { return this.___domain(this.inputs()) }; - - /** - * Return the domain of the graph. - * - * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. - */ - get codomain(): Ray { return this.___domain(this.outputs()) }; - - vertex_data = (v = int): VData => this.vertices().at(v).cast(); - edge_data = (e = int): EData => this.edges().at(e).cast(); - - // TODO: Shouldnt be here - ___next_index = (name = int(-1), index: Ray): Ray => { - // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) - const current = name === -1 ? index : Math.max(name, index); - return current + 1; - } - - /** - * Add a new vertex to the graph. - * - * @param name The value carried by this vertex (currently unused). - * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. - * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). - */ - add_vertex = (name = int(-1), vertex: VData): VData => { - this.vindex = this.___next_index(name, this.vindex); - - this.vdata[this.vindex - 1] = vertex; - return vertex; - } - - /** - * Add a new hyperedge to the graph. - * - * @param s - * @param t - */ - add_edge = (name = int(-1), edge: EData): EData => { - this.eindex = this.___next_index(name, this.eindex); - - this.edata[this.eindex - 1] = edge; - - // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) - // for v in s: - // self.vdata[v].out_edges.add(e) - // for v in t: - // self.vdata[v].in_edges.add(e) - - return edge; - } - // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. - - /** - * Remove a vertex from the graph. - * - * This removes a single vertex. - * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. - * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. - * - * @param v - * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. - */ - remove_vertex = (v = int, strict: boolean = false): Ray => { - // TODO: destroy any reference of it (could just do this lazy) - // TODO: as delegation - - if (strict) { - if (this.vertex_data(v).in_edges.count() > 0 || this.vertex_data(v).out_edges > 0) { - throw new ValueError('Attempting to remove vertex with adjacent' - + 'edges while strict == True.'); - } - - if (this.inputs().includes(v) || this.outputs.includes(v)) { - throw new ValueError('Attempting to remove boundary vertex while' - + 'strict == True.'); - - }// TODO CAN BE SIMPLIFIED - } - - // in/out edges from all vertices - delete this.vdata[v]; - } - - /** - * Remove an edge from the graph. - * - * @param e Integer identifier of the edge to remove. - */ - remove_edge = (e = int): Ray => { - // TODO: destroy any reference of it (could just do this lazy) - // in/out edges from all vertices - delete this.edata[e]; - } - - // TODO: Can these be overlaoded in properties using -=, += in TS? - - /** - * Append `inp` to the inputs of the graph. - * - * @param inp The list of vertex integer identifiers of the appended inputs. - */ - add_inputs = (inp = list(int)): Ray => { - this.inputs().continues_with(inp); // TODO: Perhaps splat - } - /** - * Append `outp` to the outputs of the graph. - * - * @param outp The list of vertex integer identifiers of the appended outputs. - */ - add_outputs = (outp = list(int)): Ray => { - this.outputs().continues_with(outp); // TODO: Perhaps splat - } - // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) - - - // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. - - // Return the list of vertex ids of the graph inputs. - get inputs(): Ray { throw new NotImplementedError(); } - // Return the list of vertex ids of the graph outputs. - get outputs(): Ray { throw new NotImplementedError(); } - - // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs - set inputs(ray = list(int)) { throw new NotImplementedError(); } - set outputs(ray = list(int)) { throw new NotImplementedError(); } - - // TODO: Move these to a "reference-like" structure, need to be on VData.. - - /** - * These are all just slightly differently abstracted in TypeScript here to make them a little more native. - */ - set_inputs = (inp = list(int)): Ray => this.inputs = inp; - set_outputs = (outp = list(int)): Ray => this.outputs = outp; - - /** - * All these are just delegations from some Vertex/Edge structure. - */ - // .vertices - num_vertices = (): Ray => this.vertices().count(); - - // .edges - num_edges = (): Ray => this.edges().count(); - - // .vertex_data - is_input = (v = int): Ray => this.vertex_data(v).is_input(); - is_output = (v = int): Ray => this.vertex_data(v).is_output(); - is_boundary = (v = int): Ray => this.vertex_data(v).is_boundary(); - in_edges = (v = int): Ray => this.vertex_data(v).in_edges; - out_edges = (v = int): Ray => this.vertex_data(v).out_edges; - - // .edge_data - source = (e = int): Ray => this.edge_data(e).source; - target = (e = int): Ray => this.edge_data(e).target; - edge_domain = (edge_id = int): Ray => this.edge_data(edge_id).domain(); - edge_codomain = (edge_id = int): Ray => this.edge_data(edge_id).codomain(); - - /** - * Return vertices that lie on a directed path from any of `vs`. - * @param vs - */ - successors = (vs = Iterable(int)): Ray => { - // TODO: Just traverse the rays, deduplicate using the index, where vs is one or more (so again which part of the ray is selected). - - - throw new NotImplementedError(); - } - - /** - * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. - * - * @param v Integer identifier of the vertex into which to merge `w`. - * @param w Integer identifier of the vertex to merge into `v`. - */ - merge_vertices = (v = int, w = int): Ray => this.vertex_data(v).merge(this.vertex_data(w)); - - /** - * Split a vertex into copies for each input, output, and tentacle. - * - * This is used for computing pushout complements of rules that aren't left-linear. - * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). - * - * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. - * - * @param v Integer identifier of vertex to be exploded. - */ - explode_vertex = (v = int): Ray => { - const vertex = this.vertex_data(v); - - // TODO; This just seems like another copy which minor changes - - const next_inputs = empty(); - const next_outputs = empty(); - - const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process - vertex: VData, - boundary: (vertex: VData) => Ray, - next_boundary: Ray - ) => { - // TODO: It's just a duplicated process for vertex/edge since their definition is separataed - - // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. - // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs()]) - // TODO: Basically a copy, and replace this one vertex - - // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. - boundary(vertex).all(e => { - const edge: EData = e.cast(); - - edge.t = edge.t - .map(target => { - if (target === v) - return target; - - const fresh_vertex = vertex.fresh(); - next_boundary.add(this.add_vertex(fresh_vertex)) - boundary(fresh_vertex).add(edge); - }) - }); - - } - - // TODO: It's always just duplicated for both ends, - __temp(vertex, (vertex) => vertex.in_edges, next_inputs); - __temp(vertex, (vertex) => vertex.out_edges, next_outputs); - - // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. - vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal - vertex.out_edges.clear(); - - // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). - this.remove_vertex(vertex, true); - - return [next_inputs, next_outputs]; - } - - - insert_id_after = (v = int): Ray => { throw new NotImplementedError(); } - - /** - * Take the monoidal product of this graph in-place with another. - * - * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. - * - * @param other - * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. - */ - tensor = (other: Graph, layout: boolean = true): Ray => { - - const a = this; - const b = other; - - const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] - - tensor.initial.y -= - tensor.initial.y.max(); // max_self - - tensor.terminal.y -= - (layout ? tensor.terminal.y.min() : 0) + 1; // min_other TODO: Why + 1 ? - - /** - * # self.set_inputs(self.inputs() + [vmap[v] for v in other.inputs()]) - * # self.set_outputs(self.outputs() + [vmap[v] for v in other.outputs()]) - * - * # Add the inputs and outputs of the other graph to this one. - * self.add_inputs([vmap[v] for v in other.inputs()]) - * self.add_outputs([vmap[v] for v in other.outputs()]) - */ - // TODO: Add equivalence/reference on the inputs/output extremes. - } - - /** - * Sequentially compose this graph in-place with another. - * - * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. - */ - compose = (other: Graph): Ray => { - // TODO Just matching outputs and inputs.. - - const a = this; - const b = other; - - // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" - const compose: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] - - // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. - - // TODO: This is just again an equivalence type check on the ends of the ray - - // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs - - { - if (compose.initial.count() !== compose.terminal.count()) - throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed - - /** - * for output_id, input_id in zip(self_outputs, other_inputs): - * output_data = self.vertex_data(output_id) - * input_data = other.vertex_data(input_id) - * if output_data.vtype != input_data.vtype: - * if not (output_data.infer_type or input_data.infer_type): - * raise GraphError( - * f'Codomain {self.codomain()} does not ' - * + f'match domain {other.domain()}' - * ) - * if output_data.size != input_data.size: - * if not (output_data.infer_size or input_data.infer_size): - * raise GraphError( - * f'Codomain {self.codomain()} does not ' - * + f'match domain {other.domain()}' - * ) - */ - } - - /** - * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. - */ - - // Compute the max x-coordinate of the edges and vertices in this graph. - - // TODO: Again, recursively going through everything defined on the initial side (outputs) - // Shift all vertices and edges of this graph below the x-axis. - compose.initial.x -= - compose.initial.x.max(); // max_self - - // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] - compose.terminal.x -= - compose.terminal.x.min(); // min_other - - // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. - /** - * plug1 = self.outputs() - * plug2 = [vmap[v] for v in other.inputs()] - * - * if len(plug1) != len(plug2): - * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' - * + f'outputs into one with {len(plug2)} inputs') - * - * self.set_outputs([vmap[v] for v in other.outputs()]) - */ - - // [outputs to inputs] - // Go through pairs of vertices from each plug - compose.zip().all(([input, output]) => { - /** - * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. - */ - - // TODO: does this ever happen??? - // while p1 in quotient: - // p1 = quotient[p1] - // while p2 in quotient: - // p2 = quotient[p2] - - - // TODO, Again the same equivalence check for loops etc.. - { - // If the resulting p1 and p2 are not the same vertex, merge them. - if (input === output) - return; - - // TODO; DO this on the vertices; - // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) - - // If both vertices have flexible types that are not equal, raise an error due to ambiguity. - // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. - - - // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. - - ['vtype', 'size'].forEach(structure => { - const infer = `infer_${structure}`; - - if (input[infer] && output[infer] && input[structure] !== output[structure]) { - throw GraphError(`Ambiguous vertex ${structure} during composition.`) - - } else if (input[infer]) { - // Otherwise, if one vertex has a flexible type, ensure the vertex types match. - // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it - // TODO: Again both sides same thing.. - input[structure] = output[structure]; // TODO: Generalized structure - input[infer] = false; - } else if (output.infer_type) { - output[structure] = input[structure]; - output[infer] = false; - } - }); - - input.merge(output); - // # Register than p2 has been merged into p1. - // quotient[p2] = p1 - } - }); - } - - /** - * Return the tensor product of this graph with another. - * - * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them - */ - __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); - - /** - * Return the composition of the current graph with `other`. - * - * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. - * @param other - */ - __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); - - /** - * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer - */ - ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { - const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. - something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? - return a_copy; // Could generalize to either end - } - - /** - * Set the `highlight` flag for a set of vertices and edges. - * - * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. - * - * @param vertices A set of vertices to highlight. - * @param edges A set of edges to highlight. - */ - highlight = (vertices = set(int), edges = set(int)): Ray => { - // TODO Again, these could be merged - this.vdata - .filter(vertex => vertices.includes(vertex)) - .all(vertex => vertex.cast().highlight = bool(true)); - this.edata - .filter(edge => edges.includes(edge)) - .all(edge => edge.cast().highlight = bool(true)); - - - } - - /** - * Clear the `highlight` flag for all vertices/edges. - * - * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. - */ - unhighlight = (): Ray => { - // TODO: These could be merged - this.vdata.highlight = false; - this.edata.highlight = false; - } -} - -export class Chyp extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - - /** - * Load a .chyp graph file from the given path. - */ - load_graph = (path = str) => { - // TODO: From localStorage for now? - // with open(path) as f: - // g = graph_from_json(f.read()) - } - - /** - * Return a graph corresponding to the identity map. - * - * This graph has a single vertex which is both an input and an output. - */ - identity = (vertex: VData): Graph => { - const graph = new Graph(); - - vertex.x = 0; // TODO automatic>? - vertex.y = 0; - graph.add_vertex(int(-1), vertex); - // TODO synce input/output automatically? - // g.set_inputs([v]) - // g.set_outputs([v]) - - return graph; - } - - - ___map_domain = (domain: Ray, _default: VData): Ray => { - return domain.map(([vtype, size], i) => { - const vertex: VData = _default.copy().cast(); - // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere - vertex.x = -1.5; - vertex.y = i - (i-1) / 2; - - return vertex; - }) - } - - /** - * Return a graph with one hyperedge and given domain and codomain. - * - * @param _default - * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. - * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. - */ - gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { - const graph = new Graph(); - - const inputs = this.___map_domain(domain, _default) - .map(vertex => graph.add_vertex(vertex)); - const outputs = this.___map_domain(codomain, _default) - .map(vertex => graph.add_vertex(vertex)); - - // TODO This is probably automatic at some point, remove - const edge = new EData(); - edge.s = inputs; - edge.t = outputs; - graph.add_edge(int(-1), edge); - // g.set_inputs(inputs) - // g.set_outputs(outputs) - - return graph; - } - - /** - * Return a graph corresponding to the given permutation. - * - * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. - * - * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. - * - * @param p A permutation given as an n-element list of integers from 0 to n-1. - * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. - */ - perm = (p = list(int), domain: Ray, _default: VData) => { - - const graph = new Graph(); - const num_wires = p.count(); - - if (num_wires !== domain.count()) - throw new GraphError(`Domain ${domain} does not match length of permutation.`) - - // TODO use ___map_domain - const inputs = domain.map(([vtype, size], i) => { - const vertex: VData = _default.copy().cast(); - // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere - vertex.x = 0; - vertex.y = i - (num_wires - 1) / 2; - - return vertex; - }) - .map(vertex => graph.add_vertex(vertex)); - // const outputs = num_wires.range(i => [inputs[p[i]]) - - // TODO Should be automatic - // g.set_inputs(inputs) - // g.set_outputs(outputs) - return graph; - } - - graph_from_json = (json_string = str): Graph => { - const json = JSON.parse(json_string().as_string()); // TODO - - const graph = new Graph(); - - // TODO: Don't do this so naively - // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), - // y=float(vd["y"] if "y" in vd else 0.0), - // value=vd["value"] if "value" in vd else "", - // name=int(v)) - // for e, ed in j["edges"].items(): - // g.add_edge(s=[int(v) for v in ed["s"]], - // t=[int(v) for v in ed["t"]], - // value=ed["value"] if "value" in ed else "", - // x=float(ed["x"]) if "x" in ed else 0.0, - // y=float(ed["y"]) if "y" in ed else 0.0, - // hyper=bool(ed["hyper"]) if "hyper" in ed else True, - // name=int(e)) - // - // g.set_inputs([int(v) for v in j["inputs"]]) - // g.set_outputs([int(v) for v in j["outputs"]]) - // json.vertices.forEach(((vertex, i) => graph.add_vertex( - // i, - // new VData() - // )); - - return graph; - } - - /** - * # def wide_id() -> Graph: - * # return gen("id", 1, 1) - * - * # def id_perm(p: List[int]) -> Graph: - * # g = Graph() - * # size = len(p) - * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] - * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] - * - * # for i in range(size): - * # y = i - (size-1)/2 - * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) - * - * # g.set_inputs(inputs) - * # g.set_outputs(outputs) - * - * # return g - */ - - /** - * Return a graph corresponding to a vertex size redistribution. - * - * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. - * - * More generally, a conversion can be done between different lists of sizes, for some vertex type. - */ - redistributer = (domain = list, codomain = list) => { - - } -} - -export class CodeView extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - popup_visible = (): Ray => { throw new NotImplementedError(); } - set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } - ident_at_cursor = (): Ray => { throw new NotImplementedError(); } - insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } - keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } - set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } - add_line_below = (text = str): Ray => { throw new NotImplementedError(); } -} - -export class CodeCompletionModel extends Ray { - __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } - set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } - data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } - rowCount = (): Ray => { throw new NotImplementedError(); } -} - -export class ChypDocument extends Ray { - __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } - confirm_close = (): Ray => { throw new NotImplementedError(); } - add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } - open = (file_name = str): Ray => { throw new NotImplementedError(); } - save = (): Ray => { throw new NotImplementedError(); } - save_as = (): Ray => { throw new NotImplementedError(); } -} - -export class Editor extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - title = (): Ray => { throw new NotImplementedError(); } - reset_state = (): Ray => { throw new NotImplementedError(); } - invalidate_text = (): Ray => { throw new NotImplementedError(); } - next_part = (): Ray => { throw new NotImplementedError(); } - jump_to_error = (): Ray => { throw new NotImplementedError(); } - show_errors = (): Ray => { throw new NotImplementedError(); } - show_at_cursor = (): Ray => { throw new NotImplementedError(); } - next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } - repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } - update_state = (): Ray => { throw new NotImplementedError(); } - import_at_cursor = (): Ray => { throw new NotImplementedError(); } -} - -export class CheckThread extends Ray { - __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } - run = (): Ray => { throw new NotImplementedError(); } -} - -export class ErrorListModel extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } - data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } - headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } - index = (row = int, column = int): Ray => { throw new NotImplementedError(); } - columnCount = (): Ray => { throw new NotImplementedError(); } - rowCount = (): Ray => { throw new NotImplementedError(); } - parent = (): Ray => { throw new NotImplementedError(); } -} - -export class EItem extends Ray { - __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } - paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } -} - -export class VItem extends Ray { - __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } - refresh = (): Ray => { throw new NotImplementedError(); } -} - -export class TItem extends Ray { - __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } - refresh = (): Ray => { throw new NotImplementedError(); } -} - -export class GraphScene extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } - add_items = (): Ray => { throw new NotImplementedError(); } - mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } - mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } - mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } -} - -export class GraphView extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } -} - -export class ChypHighlighter extends Ray { - __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } - set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } - highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } -} - -export class MainWindow extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - remove_empty_editor = (): Ray => { throw new NotImplementedError(); } - update_file_name = (): Ray => { throw new NotImplementedError(); } - tab_changed = (i = int): Ray => { throw new NotImplementedError(); } - update_themes = (): Ray => { throw new NotImplementedError(); } - recent_files = (): Ray => { throw new NotImplementedError(); } - update_recent_files = (): Ray => { throw new NotImplementedError(); } - add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } - close_tab = (): Ray => { throw new NotImplementedError(); } - new = (): Ray => { throw new NotImplementedError(); } - open = (): Ray => { throw new NotImplementedError(); } - save = (): Ray => { throw new NotImplementedError(); } - save_as = (): Ray => { throw new NotImplementedError(); } - undo = (): Ray => { throw new NotImplementedError(); } - redo = (): Ray => { throw new NotImplementedError(); } - show_errors = (): Ray => { throw new NotImplementedError(); } - add_rewrite_step = (): Ray => { throw new NotImplementedError(); } - repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } - next_rewrite = (): Ray => { throw new NotImplementedError(); } - next_part = (): Ray => { throw new NotImplementedError(); } - previous_part = (): Ray => { throw new NotImplementedError(); } - next_tab = (): Ray => { throw new NotImplementedError(); } - previous_tab = (): Ray => { throw new NotImplementedError(); } - goto_import = (): Ray => { throw new NotImplementedError(); } - closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } - build_menu = (): Ray => { throw new NotImplementedError(); } -} - -// TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? -export class Match extends Ray { - - get domain(): Graph { throw new NotImplementedError(); } - get codomain(): Graph { throw new NotImplementedError(); } - get vertex_map(): Ray { throw new NotImplementedError(); } - get vertex_image(): Ray { throw new NotImplementedError(); } - get edge_map(): Ray { throw new NotImplementedError(); } - get edge_image(): Ray { throw new NotImplementedError(); } - - __init__ = (): Ray => { throw new NotImplementedError(); } - __str__ = (): Ray => { - // (f'\tVertex map: {str(self.vertex_map)}' - // + f'\n\tEdge map: {str(self.edge_map)}') - // TODO - throw new NotImplementedError(); } - - // Implemented on Ray - // TODO; doesnt copy the graphs at domain/codomain - // copy = (): Ray => { throw new NotImplementedError(); } - - /** - * Try to map `domain_vertex` to `codomain_vertex`. - * - * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. - * - * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. - */ - try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { - - // If the vertex is already mapped, only check the new mapping is consistent with the current match. - if (this.vertex_map.includes(domain_vertex)) { - log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) - return this.vertex_map[domain_vertex] === codomain_vertex; - } - - // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. - // TODO: This should all be redundant, probably removed ... - - // Ensure the mapping preserves vertex type. - if (domain_vertex.vtype !== codomain_vertex.vtype) { - log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); - - return bool(False); - } - - // Ensure the mapping preserves vertex size. - if (domain_vertex.size !== codomain_vertex.size) { - log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) - return bool(False); - } - - // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. - if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { - log('Vertex failed: codomain vertex is boundary but domain vertex is not.') - return bool(False); - } - - // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. - if (this.vertex_image.includes(codomain_vertex)) { - // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. - if (!domain_vertex.is_boundary()) { - log('Vertex failed: non-injective on interior vertex.') - return bool(False); - } - - // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. - if (this.vertex_image.any(([mapped_vertex, image_vertex]) => - image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! - )) { - log('Vertex failed: non-injective on interior vertex.') - return bool(False); - } - - return bool(False); - } - - // If a new and consistent map is found, add it to the vertex map of this match. - this.vertex_map[domain_vertex] = codomain_vertex - this.vertex_image.add(codomain_vertex) - - // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. - - if (!domain_vertex.is_boundary()) { - if (domain_vertex.in_edges.count() !== codomain_vertex.in_edges.count()) { - log('Vertex failed: in_edges cannot satisfy gluing conditions.') - return bool(False) - } - if (domain_vertex.out_edges.count() !== codomain_vertex.out_edges.count()) { - log('Vertex failed: in_edges cannot satisfy gluing conditions.') - return bool(False) - } - } - - // If a new consistent map is added that satisfies the gluing conditions, we are successful. - log('Vertex success.') - return bool(True); - } - - try_add_edge = (domain_edge = int, codomain_edge = int): Ray => { throw new NotImplementedError(); } - domain_neighbourhood_mapped = (vertex = int): Ray => { throw new NotImplementedError(); } - map_scalars = (): Ray => { throw new NotImplementedError(); } - more = (): Ray => { throw new NotImplementedError(); } - is_total = (): Ray => { throw new NotImplementedError(); } - is_surjective = (): Ray => { throw new NotImplementedError(); } - is_injective = (): Ray => { throw new NotImplementedError(); } - is_convex = (): Ray => { throw new NotImplementedError(); } - - /** - * TODO Not implemented;; - * # def cod_nhd_mapped(self, cod_v: int): - * # """Returns True if nhd(cod_v) is the range of emap""" - * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and - * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) - */ -} - -export class Matches extends Ray { - __init__ = (domain = Graph, codomain = Graph): Ray => { throw new NotImplementedError(); } - __iter__ = (): Ray => { throw new NotImplementedError(); } - __next__ = (): Ray => { throw new NotImplementedError(); } -} - -export class Rule extends Ray { - get lhs(): Graph { throw new NotImplementedError(); } - get rhs(): Graph { throw new NotImplementedError(); } - - /** - * TODO: Put the name on each side of the rule, not the '-' hacky thing - */ - get name(): Ray { throw new NotImplementedError(); } - get equiv(): Ray { throw new NotImplementedError(); } - - __init__ = (name = str(''), equiv = bool(True)): Ray => { - // TODO: Maybe just move exception to a method on this thing - - if (this.lhs.domain !== this.rhs.domain) // TODO: !== - throw new RuleError(`Inputs must match on LHS and RHS of rule (${this.rhs.domain} != ${this.lhs.domain})`); - - if (this.lhs.codomain !== this.rhs.codomain) - throw new RuleError(`Outputs must match on LHS and RHS of rule (${this.rhs.codomain} != ${this.lhs.codomain})`) - - - throw new NotImplementedError(); - - } - - copy = (): Ray => { throw new NotImplementedError(); } - - // TODO: Could put this on ray, generalize to swapping - converse = (): Rule => { - // TODO remove this hacky thing - just tries to us -a / a - const name = this.name.as_string().startsWith('-') ? this.name.substring(1) : `-${this.name}`; - - const converse: Rule = this.copy().cast(); // TODO equiv=True? - converse.name = name; - - // TODO: Wont work, we just should swap initial/terminal;\ - //swap?? or change direction.. - // const swap = converse.rhs; - // converse.rhs = converse.lhs; - // converse.lhs = swap; - return converse; - } - - /** - * Returns True if boundary on lhs embeds injectively - */ - is_left_linear = (): Ray => { - // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading - return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() - .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. - } - - /** - * Do double-pushout rewriting - * - * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. - * @param match - */ - dpo = (match: Match): Ray => { - // if (!this.is_left_linear()) - // throw new NotImplementedError("Only left linear rules are supported for now") - - const rewritten_graph: Graph = match.codomain.copy(); - - // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? - - // Computes the push complement ?? (just the thing we're replacing right?) - // TODO: Removes the match from the copy? - this.lhs.edges().all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); - - const inputs = []; - const outputs = []; - - this.lhs.vertices().all(rule_vertex => { - const match_vertex = match.vertex_map[rule_vertex]; - - if (!this.lhs.is_boundary(rule_vertex)) { - rewritten_graph.remove_vertex(match_vertex); - return; - } - - const rule_input = this.lhs.vertex_data(rule_vertex).in_indices; - const rule_output = this.lhs.vertex_data(rule_vertex).out_indices; - - if (rule_input.count() === 1 && rule_output === 1) { - const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); - - if (match_input.count() !== 1 && match_output.count() !== 1) - throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); - - inputs[rule_vertex] = match_input[0]; - outputs[rule_vertex] = match_output[0]; - } else if (rule_input.count() > 1 || rule_output.count() > 1) { - throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); - } - }) - - // Embed Rule.rhs into rewritten_graph - const replacement = new Match(this.rhs, rewritten_graph); - - return replacement; - } - - /** - * Apply the given rewrite r to at match m and return the first result - * - * This is a convience wrapper for `dpo` for when the extra rewrite data isn't needed. - */ - rewrite = (match: Match): Graph => { - // TODO: except StopIteration: - // raise RuntimeError("Rewrite has no valid context") - - const result: Match = this.dpo(match).first().cast(); - return result.codomain; - } -} - -export class RewriteState extends Ray { - __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } -} - -export class State extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } - part_at = (pos = int): Ray => { throw new NotImplementedError(); } - var = (items = List(Any)): Ray => { throw new NotImplementedError(); } - module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } - num = (items = List(Any)): Ray => { throw new NotImplementedError(); } - type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } - type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } - id = (items = list(Any)): Ray => { throw new NotImplementedError(); } - id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } - eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } - le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } - perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } - size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } - par = (items = List(Any)): Ray => { throw new NotImplementedError(); } - gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } - color = (items = List(Any)): Ray => { throw new NotImplementedError(); } - import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } - tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } - nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } -} - -export class Tactic extends Ray { - __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } - repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } - error = (message = str): Ray => { throw new NotImplementedError(); } - has_goal = (): Ray => { throw new NotImplementedError(); } - global_rules = (): Ray => { throw new NotImplementedError(); } - lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } - add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } - add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } - __lhs = (target = str): Ray => { throw new NotImplementedError(); } - __rhs = (target = str): Ray => { throw new NotImplementedError(); } - __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } - __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } - rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } - rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } - rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } - rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } - validate_goal = (): Ray => { throw new NotImplementedError(); } - lhs = (): Ray => { throw new NotImplementedError(); } - rhs = (): Ray => { throw new NotImplementedError(); } - lhs_size = (): Ray => { throw new NotImplementedError(); } - rhs_size = (): Ray => { throw new NotImplementedError(); } - highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } - highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } - __reset = (): Ray => { throw new NotImplementedError(); } - next_rhs = (current = str): Ray => { throw new NotImplementedError(); } - run_check = (): Ray => { throw new NotImplementedError(); } - name = (): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } - make_rhs = (): Ray => { throw new NotImplementedError(); } -} - -export class RuleTac extends Ray { - name = (): Ray => { throw new NotImplementedError(); } - make_rhs = (): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } -} - -export class SimpTac extends Ray { - name = (): Ray => { throw new NotImplementedError(); } - __prepare_rules = (): Ray => { throw new NotImplementedError(); } - make_rhs = (): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } -} - +// import {Arbitrary, empty, JS, Ray} from "../../../explorer/Ray"; +// import { NotImplementedError } from "../../../explorer/errors/errors"; +// import {Option} from "../../../js/utils/Option"; +// +// /** +// * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. +// * GitHub: https://github.com/akissinger/chyp +// * +// * A simple way of phrasing this conversion, is that the concept of a 'Vertex', 'Edge', 'Graph', 'Rule', ..., 'Rewrite' are merged into one thing: a Ray. +// * +// * NOTE: +// * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. +// * +// * - The .copy()'s are implemented on Ray. +// * +// * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. +// * +// * TODO: Probably want all these types at runtime, to display them +// * +// * TODO: Graph boundary is automatic with this structure? +// * +// * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? +// * +// * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. +// * +// * TODO: Can just move the terminal which holds the oointer to the boundary +// * +// * TODO: Automatically generate visual examples of all the methods +// * +// * TODO: Runtime errors as rays +// * +// * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph +// */ +// +// export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// +// export class ValueError extends Error {} +// +// /** +// * Non-default vertex types are identified by a string label +// * +// * str() | None() - No overloading in TypeScript ;( +// */ +// export const VType = JS.Iterable([str, None]); +// +// /** +// * An error occurred in the graph backend. +// * +// * TODO probably hooked as a boolean, one successful the other not +// */ +// export class GraphError extends Error {} +// export class RuleError extends Error {} +// +// /** +// * Used for debugging (the matcher) +// */ +// const DEBUG = true; // TODO; Generalize +// const log = (s: string) => { +// if (!DEBUG) +// return; +// +// console.log(s); +// } +// +// /** +// * Data associated with a single vertex. +// */ +// export class VData extends Ray { +// +// // The vertex type. +// get vtype(): Ray { throw new NotImplementedError(); } +// +// /** +// * The register size (number of bundled parallel wires) of the vertex. +// * +// * TODO: Just a counter over a line +// */ +// get size(): Ray { throw new NotImplementedError(); } +// +// /** +// * Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). +// */ +// get infer_type(): Ray { throw new NotImplementedError(); } +// +// /** +// * Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). +// */ +// get infer_size(): Ray { throw new NotImplementedError(); } +// +// +// /** +// * TODO: These coordinates used for inferences? +// * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" +// */ +// +// // x-coordinate at which to draw the vertex. +// get x(): Ray { throw new NotImplementedError(); } +// // y-coordinate at which to draw the vertex. +// get y(): Ray { throw new NotImplementedError(); } +// +// // TODO: Just some boolean +// get highlight(): Ray { throw new NotImplementedError(); } +// +// get value(): Ray { throw new NotImplementedError(); } +// +// /** +// * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. +// * +// * TODO ; // set[int] = set() +// * TODO ; these are just the initial/terminal sides of a Ray. they're just duplicated +// */ +// get in_edges(): Ray { throw new NotImplementedError(); } +// get out_edges(): Ray { throw new NotImplementedError(); } +// +// /** +// * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. +// */ +// get in_indices(): Ray { return this.initial } // +// get out_indices(): Ray { throw new NotImplementedError(); } +// +// /** +// * Initialize a VData instance. +// */ +// __init__ = (): Ray => { +// this.highlight = bool(False); +// this.in_edges = set(int); +// this.out_edges = set(int); +// this.in_indices = set(int); +// this.out_indices = set(int); +// } +// +// +// is_input = (): Ray => this.in_indices.count() > 0; +// is_output = (): Ray => this.out_indices.count() > 0; +// is_boundary = (): Ray => this.is_input() || this.is_output(); +// +// // TODO: Probably generalizable +// +// /** +// * +// * @param other +// */ +// merge = (other: VData): Ray => { +// // TODO: other is destroyed +// // TODO: Vertices +// // this.initial.equivalent(other.initial); +// // this.terminal.equivalent(other.initial); +// +// /* +// +// vd = self.vertex_data(v) +// # print("merging %s <- %s" % (v, w)) +// +// # Where vertex `w` occurs as an edge target, replace it with `v` +// for e in self.in_edges(w): +// ed = self.edge_data(e) +// ed.t = [v if x == w else x for x in ed.t] +// vd.in_edges.add(e) +// +// # Where vertex `w` occurs as an edge source, replace it with `v` +// for e in self.out_edges(w): +// ed = self.edge_data(e) +// ed.s = [v if x == w else x for x in ed.s] +// vd.out_edges.add(e) +// +// # Wherever `w` occurs on the graph boundary, replace it with `v` +// self.set_inputs([v if x == w else x for x in self.inputs()]) +// self.set_outputs([v if x == w else x for x in self.outputs()]) +// +// # Remove references to `w` from the graph +// self.remove_vertex(w) +// +// */ +// +// throw new NotImplementedError(); +// } +// +// fresh = (): VData => { +// // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. +// +// // vtype=vd.vtype, size=vd.size, +// // x=vd.x, y=vd.y, value=vd.value +// +// } +// } +// +// /** +// * Data associated with a single edge. +// */ +// export class EData extends Ray { +// +// // TODO: this is just the initial frame +// get s(): Ray { throw new NotImplementedError(); } +// +// // TODO: this is just the terminal frame +// get t(): Ray { throw new NotImplementedError(); } +// +// +// get x(): Ray { throw new NotImplementedError(); } +// get y(): Ray { throw new NotImplementedError(); } +// get fg(): Ray { throw new NotImplementedError(); } +// get bg(): Ray { throw new NotImplementedError(); } +// get highlight(): Ray { throw new NotImplementedError(); } +// get hyper(): Ray { throw new NotImplementedError(); } +// get value(): Ray { throw new NotImplementedError(); } +// +// __init__ = (): Ray => { +// this.s = empty(); +// this.t = empty(); +// this.highlight = bool(False); +// } +// +// __repr__ = (): Ray => { throw new NotImplementedError(); +// // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' +// } +// +// // TODO: More stuff to relate it to the screen that shouldnt be here. +// /** +// * Return how many width 'units' this box needs to display nicely. +// * +// * This uses a simple rule: +// * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. +// * - Otherwise draw as a larger (size 2) box. +// */ +// box_size = (): Ray => (this.s.count() <= 1 && this.t.count() <= 1) ? 1 : 2; +// +// toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL +// +// get source() { return this.s }; +// get target() { return this.t }; +// +// // TODO: Shouldn't be here, this should either be implemented on Ray if it's general enough, of just remain here as an artifact +// protected ___domain = (ray: Ray) => ray.map(_ => { +// const vertex: VData = _.cast(); +// return [vertex.vtype, vertex.size]; +// }); +// +// domain = (): Ray => this.___domain(this.source); +// codomain = (): Ray => this.___domain(this.target); +// +// } +// +// /** +// * A hypergraph with boundaries. +// * +// * This is the main data structure used by Chyp. It represents a directed +// * hypergraph (which we call simply a "graph") as two dictionaries for +// * vertices and (hyper)edges, respectively. Each vertex is associated with a +// * `VData` object and edge edge with an `EData` object, which stores +// * information about adjacency, position, label, etc. +// * +// * The particular flavor of hypergraphs we use associate to each hyperedge a +// * list of source vertices and a list of target vertices. The hypergraph +// * itself also has a list of input vertices and a list of output vertices, +// * which are used for sequential composition and rewriting. +// */ +// export class Graph extends Ray { +// +// // Mapping from integer identifiers of each vertex to its data. +// get vdata(): Ray { throw new NotImplementedError(); } +// // Mapping from integer identifiers of each hyperedge to its data. +// get edata(): Ray { throw new NotImplementedError(); } +// +// // TODO: Can probably generate these on the fly, or cache them automatically +// get vindex(): Ray { return this.vdata.index.max(0); } +// get eindex(): Ray { return this.edata.index.max(0); } +// +// // TODO .keys +// vertices = (): Ray => this.vdata; +// edges = (): Ray => this.edata; +// +// // TODO: Shouldn't be here, this should either be implemented on Ray if it's general enough, of just remain here as an artifact +// protected ___domain = (ray: Ray) => ray.map(_ => { +// const vertex: VData = _.cast(); +// return [vertex.vtype, vertex.size]; +// }); +// +// /** +// * Return the domain of the graph. +// * +// * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. +// */ +// // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. +// get domain(): Ray { return this.___domain(this.inputs()) }; +// +// /** +// * Return the domain of the graph. +// * +// * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. +// */ +// get codomain(): Ray { return this.___domain(this.outputs()) }; +// +// vertex_data = (v = int): VData => this.vertices().at(v).cast(); +// edge_data = (e = int): EData => this.edges().at(e).cast(); +// +// // TODO: Shouldnt be here +// ___next_index = (name = int(-1), index: Ray): Ray => { +// // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) +// const current = name === -1 ? index : Math.max(name, index); +// return current + 1; +// } +// +// /** +// * Add a new vertex to the graph. +// * +// * @param name The value carried by this vertex (currently unused). +// * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. +// * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). +// */ +// add_vertex = (name = int(-1), vertex: VData): VData => { +// this.vindex = this.___next_index(name, this.vindex); +// +// this.vdata[this.vindex - 1] = vertex; +// return vertex; +// } +// +// /** +// * Add a new hyperedge to the graph. +// * +// * @param s +// * @param t +// */ +// add_edge = (name = int(-1), edge: EData): EData => { +// this.eindex = this.___next_index(name, this.eindex); +// +// this.edata[this.eindex - 1] = edge; +// +// // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) +// // for v in s: +// // self.vdata[v].out_edges.add(e) +// // for v in t: +// // self.vdata[v].in_edges.add(e) +// +// return edge; +// } +// // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. +// +// /** +// * Remove a vertex from the graph. +// * +// * This removes a single vertex. +// * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. +// * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. +// * +// * @param v +// * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. +// */ +// remove_vertex = (v = int, strict: boolean = false): Ray => { +// // TODO: destroy any reference of it (could just do this lazy) +// // TODO: as delegation +// +// if (strict) { +// if (this.vertex_data(v).in_edges.count() > 0 || this.vertex_data(v).out_edges > 0) { +// throw new ValueError('Attempting to remove vertex with adjacent' +// + 'edges while strict == True.'); +// } +// +// if (this.inputs().includes(v) || this.outputs.includes(v)) { +// throw new ValueError('Attempting to remove boundary vertex while' +// + 'strict == True.'); +// +// }// TODO CAN BE SIMPLIFIED +// } +// +// // in/out edges from all vertices +// delete this.vdata[v]; +// } +// +// /** +// * Remove an edge from the graph. +// * +// * @param e Integer identifier of the edge to remove. +// */ +// remove_edge = (e = int): Ray => { +// // TODO: destroy any reference of it (could just do this lazy) +// // in/out edges from all vertices +// delete this.edata[e]; +// } +// +// // TODO: Can these be overlaoded in properties using -=, += in TS? +// +// /** +// * Append `inp` to the inputs of the graph. +// * +// * @param inp The list of vertex integer identifiers of the appended inputs. +// */ +// add_inputs = (inp = list(int)): Ray => { +// this.inputs().continues_with(inp); // TODO: Perhaps splat +// } +// /** +// * Append `outp` to the outputs of the graph. +// * +// * @param outp The list of vertex integer identifiers of the appended outputs. +// */ +// add_outputs = (outp = list(int)): Ray => { +// this.outputs().continues_with(outp); // TODO: Perhaps splat +// } +// // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) +// +// +// // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. +// +// // Return the list of vertex ids of the graph inputs. +// get inputs(): Ray { throw new NotImplementedError(); } +// // Return the list of vertex ids of the graph outputs. +// get outputs(): Ray { throw new NotImplementedError(); } +// +// // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs +// set inputs(ray = list(int)) { throw new NotImplementedError(); } +// set outputs(ray = list(int)) { throw new NotImplementedError(); } +// +// // TODO: Move these to a "reference-like" structure, need to be on VData.. +// +// /** +// * These are all just slightly differently abstracted in TypeScript here to make them a little more native. +// */ +// set_inputs = (inp = list(int)): Ray => this.inputs = inp; +// set_outputs = (outp = list(int)): Ray => this.outputs = outp; +// +// /** +// * All these are just delegations from some Vertex/Edge structure. +// */ +// // .vertices +// num_vertices = (): Ray => this.vertices().count(); +// +// // .edges +// num_edges = (): Ray => this.edges().count(); +// +// // .vertex_data +// is_input = (v = int): Ray => this.vertex_data(v).is_input(); +// is_output = (v = int): Ray => this.vertex_data(v).is_output(); +// is_boundary = (v = int): Ray => this.vertex_data(v).is_boundary(); +// in_edges = (v = int): Ray => this.vertex_data(v).in_edges; +// out_edges = (v = int): Ray => this.vertex_data(v).out_edges; +// +// // .edge_data +// source = (e = int): Ray => this.edge_data(e).source; +// target = (e = int): Ray => this.edge_data(e).target; +// edge_domain = (edge_id = int): Ray => this.edge_data(edge_id).domain(); +// edge_codomain = (edge_id = int): Ray => this.edge_data(edge_id).codomain(); +// +// /** +// * Return vertices that lie on a directed path from any of `vs`. +// * @param vs +// */ +// successors = (vs = Iterable(int)): Ray => { +// // TODO: Just traverse the rays, deduplicate using the index, where vs is one or more (so again which part of the ray is selected). +// +// +// throw new NotImplementedError(); +// } +// +// /** +// * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. +// * +// * @param v Integer identifier of the vertex into which to merge `w`. +// * @param w Integer identifier of the vertex to merge into `v`. +// */ +// merge_vertices = (v = int, w = int): Ray => this.vertex_data(v).merge(this.vertex_data(w)); +// +// /** +// * Split a vertex into copies for each input, output, and tentacle. +// * +// * This is used for computing pushout complements of rules that aren't left-linear. +// * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). +// * +// * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. +// * +// * @param v Integer identifier of vertex to be exploded. +// */ +// explode_vertex = (v = int): Ray => { +// const vertex = this.vertex_data(v); +// +// // TODO; This just seems like another copy which minor changes +// +// const next_inputs = empty(); +// const next_outputs = empty(); +// +// const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process +// vertex: VData, +// boundary: (vertex: VData) => Ray, +// next_boundary: Ray +// ) => { +// // TODO: It's just a duplicated process for vertex/edge since their definition is separataed +// +// // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. +// // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs()]) +// // TODO: Basically a copy, and replace this one vertex +// +// // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. +// boundary(vertex).all(e => { +// const edge: EData = e.cast(); +// +// edge.t = edge.t +// .map(target => { +// if (target === v) +// return target; +// +// const fresh_vertex = vertex.fresh(); +// next_boundary.add(this.add_vertex(fresh_vertex)) +// boundary(fresh_vertex).add(edge); +// }) +// }); +// +// } +// +// // TODO: It's always just duplicated for both ends, +// __temp(vertex, (vertex) => vertex.in_edges, next_inputs); +// __temp(vertex, (vertex) => vertex.out_edges, next_outputs); +// +// // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. +// vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal +// vertex.out_edges.clear(); +// +// // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). +// this.remove_vertex(vertex, true); +// +// return [next_inputs, next_outputs]; +// } +// +// +// insert_id_after = (v = int): Ray => { throw new NotImplementedError(); } +// +// /** +// * Take the monoidal product of this graph in-place with another. +// * +// * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. +// * +// * @param other +// * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. +// */ +// tensor = (other: Graph, layout: boolean = true): Ray => { +// +// const a = this; +// const b = other; +// +// const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] +// +// tensor.initial.y -= +// tensor.initial.y.max(); // max_self +// +// tensor.terminal.y -= +// (layout ? tensor.terminal.y.min() : 0) + 1; // min_other TODO: Why + 1 ? +// +// /** +// * # self.set_inputs(self.inputs() + [vmap[v] for v in other.inputs()]) +// * # self.set_outputs(self.outputs() + [vmap[v] for v in other.outputs()]) +// * +// * # Add the inputs and outputs of the other graph to this one. +// * self.add_inputs([vmap[v] for v in other.inputs()]) +// * self.add_outputs([vmap[v] for v in other.outputs()]) +// */ +// // TODO: Add equivalence/reference on the inputs/output extremes. +// } +// +// /** +// * Sequentially compose this graph in-place with another. +// * +// * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. +// */ +// compose = (other: Graph): Ray => { +// // TODO Just matching outputs and inputs.. +// +// const a = this; +// const b = other; +// +// // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" +// const compose: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] +// +// // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. +// +// // TODO: This is just again an equivalence type check on the ends of the ray +// +// // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs +// +// { +// if (compose.initial.count() !== compose.terminal.count()) +// throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed +// +// /** +// * for output_id, input_id in zip(self_outputs, other_inputs): +// * output_data = self.vertex_data(output_id) +// * input_data = other.vertex_data(input_id) +// * if output_data.vtype != input_data.vtype: +// * if not (output_data.infer_type or input_data.infer_type): +// * raise GraphError( +// * f'Codomain {self.codomain()} does not ' +// * + f'match domain {other.domain()}' +// * ) +// * if output_data.size != input_data.size: +// * if not (output_data.infer_size or input_data.infer_size): +// * raise GraphError( +// * f'Codomain {self.codomain()} does not ' +// * + f'match domain {other.domain()}' +// * ) +// */ +// } +// +// /** +// * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. +// */ +// +// // Compute the max x-coordinate of the edges and vertices in this graph. +// +// // TODO: Again, recursively going through everything defined on the initial side (outputs) +// // Shift all vertices and edges of this graph below the x-axis. +// compose.initial.x -= +// compose.initial.x.max(); // max_self +// +// // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] +// compose.terminal.x -= +// compose.terminal.x.min(); // min_other +// +// // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. +// /** +// * plug1 = self.outputs() +// * plug2 = [vmap[v] for v in other.inputs()] +// * +// * if len(plug1) != len(plug2): +// * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' +// * + f'outputs into one with {len(plug2)} inputs') +// * +// * self.set_outputs([vmap[v] for v in other.outputs()]) +// */ +// +// // [outputs to inputs] +// // Go through pairs of vertices from each plug +// compose.zip().all(([input, output]) => { +// /** +// * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. +// */ +// +// // TODO: does this ever happen??? +// // while p1 in quotient: +// // p1 = quotient[p1] +// // while p2 in quotient: +// // p2 = quotient[p2] +// +// +// // TODO, Again the same equivalence check for loops etc.. +// { +// // If the resulting p1 and p2 are not the same vertex, merge them. +// if (input === output) +// return; +// +// // TODO; DO this on the vertices; +// // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) +// +// // If both vertices have flexible types that are not equal, raise an error due to ambiguity. +// // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. +// +// +// // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. +// +// ['vtype', 'size'].forEach(structure => { +// const infer = `infer_${structure}`; +// +// if (input[infer] && output[infer] && input[structure] !== output[structure]) { +// throw GraphError(`Ambiguous vertex ${structure} during composition.`) +// +// } else if (input[infer]) { +// // Otherwise, if one vertex has a flexible type, ensure the vertex types match. +// // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it +// // TODO: Again both sides same thing.. +// input[structure] = output[structure]; // TODO: Generalized structure +// input[infer] = false; +// } else if (output.infer_type) { +// output[structure] = input[structure]; +// output[infer] = false; +// } +// }); +// +// input.merge(output); +// // # Register than p2 has been merged into p1. +// // quotient[p2] = p1 +// } +// }); +// } +// +// /** +// * Return the tensor product of this graph with another. +// * +// * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them +// */ +// __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); +// +// /** +// * Return the composition of the current graph with `other`. +// * +// * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. +// * @param other +// */ +// __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); +// +// /** +// * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer +// */ +// ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { +// const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. +// something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? +// return a_copy; // Could generalize to either end +// } +// +// /** +// * Set the `highlight` flag for a set of vertices and edges. +// * +// * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. +// * +// * @param vertices A set of vertices to highlight. +// * @param edges A set of edges to highlight. +// */ +// highlight = (vertices = set(int), edges = set(int)): Ray => { +// // TODO Again, these could be merged +// this.vdata +// .filter(vertex => vertices.includes(vertex)) +// .all(vertex => vertex.cast().highlight = bool(true)); +// this.edata +// .filter(edge => edges.includes(edge)) +// .all(edge => edge.cast().highlight = bool(true)); +// +// +// } +// +// /** +// * Clear the `highlight` flag for all vertices/edges. +// * +// * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. +// */ +// unhighlight = (): Ray => { +// // TODO: These could be merged +// this.vdata.highlight = false; +// this.edata.highlight = false; +// } +// } +// +// export class Chyp extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// +// /** +// * Load a .chyp graph file from the given path. +// */ +// load_graph = (path = str) => { +// // TODO: From localStorage for now? +// // with open(path) as f: +// // g = graph_from_json(f.read()) +// } +// +// /** +// * Return a graph corresponding to the identity map. +// * +// * This graph has a single vertex which is both an input and an output. +// */ +// identity = (vertex: VData): Graph => { +// const graph = new Graph(); +// +// vertex.x = 0; // TODO automatic>? +// vertex.y = 0; +// graph.add_vertex(int(-1), vertex); +// // TODO synce input/output automatically? +// // g.set_inputs([v]) +// // g.set_outputs([v]) +// +// return graph; +// } +// +// +// ___map_domain = (domain: Ray, _default: VData): Ray => { +// return domain.map(([vtype, size], i) => { +// const vertex: VData = _default.copy().cast(); +// // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere +// vertex.x = -1.5; +// vertex.y = i - (i-1) / 2; +// +// return vertex; +// }) +// } +// +// /** +// * Return a graph with one hyperedge and given domain and codomain. +// * +// * @param _default +// * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. +// * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. +// */ +// gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { +// const graph = new Graph(); +// +// const inputs = this.___map_domain(domain, _default) +// .map(vertex => graph.add_vertex(vertex)); +// const outputs = this.___map_domain(codomain, _default) +// .map(vertex => graph.add_vertex(vertex)); +// +// // TODO This is probably automatic at some point, remove +// const edge = new EData(); +// edge.s = inputs; +// edge.t = outputs; +// graph.add_edge(int(-1), edge); +// // g.set_inputs(inputs) +// // g.set_outputs(outputs) +// +// return graph; +// } +// +// /** +// * Return a graph corresponding to the given permutation. +// * +// * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. +// * +// * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. +// * +// * @param p A permutation given as an n-element list of integers from 0 to n-1. +// * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. +// */ +// perm = (p = list(int), domain: Ray, _default: VData) => { +// +// const graph = new Graph(); +// const num_wires = p.count(); +// +// if (num_wires !== domain.count()) +// throw new GraphError(`Domain ${domain} does not match length of permutation.`) +// +// // TODO use ___map_domain +// const inputs = domain.map(([vtype, size], i) => { +// const vertex: VData = _default.copy().cast(); +// // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere +// vertex.x = 0; +// vertex.y = i - (num_wires - 1) / 2; +// +// return vertex; +// }) +// .map(vertex => graph.add_vertex(vertex)); +// // const outputs = num_wires.range(i => [inputs[p[i]]) +// +// // TODO Should be automatic +// // g.set_inputs(inputs) +// // g.set_outputs(outputs) +// return graph; +// } +// +// graph_from_json = (json_string = str): Graph => { +// const json = JSON.parse(json_string().as_string()); // TODO +// +// const graph = new Graph(); +// +// // TODO: Don't do this so naively +// // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), +// // y=float(vd["y"] if "y" in vd else 0.0), +// // value=vd["value"] if "value" in vd else "", +// // name=int(v)) +// // for e, ed in j["edges"].items(): +// // g.add_edge(s=[int(v) for v in ed["s"]], +// // t=[int(v) for v in ed["t"]], +// // value=ed["value"] if "value" in ed else "", +// // x=float(ed["x"]) if "x" in ed else 0.0, +// // y=float(ed["y"]) if "y" in ed else 0.0, +// // hyper=bool(ed["hyper"]) if "hyper" in ed else True, +// // name=int(e)) +// // +// // g.set_inputs([int(v) for v in j["inputs"]]) +// // g.set_outputs([int(v) for v in j["outputs"]]) +// // json.vertices.forEach(((vertex, i) => graph.add_vertex( +// // i, +// // new VData() +// // )); +// +// return graph; +// } +// +// /** +// * # def wide_id() -> Graph: +// * # return gen("id", 1, 1) +// * +// * # def id_perm(p: List[int]) -> Graph: +// * # g = Graph() +// * # size = len(p) +// * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] +// * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] +// * +// * # for i in range(size): +// * # y = i - (size-1)/2 +// * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) +// * +// * # g.set_inputs(inputs) +// * # g.set_outputs(outputs) +// * +// * # return g +// */ +// +// /** +// * Return a graph corresponding to a vertex size redistribution. +// * +// * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. +// * +// * More generally, a conversion can be done between different lists of sizes, for some vertex type. +// */ +// redistributer = (domain = list, codomain = list) => { +// +// } +// } +// +// export class CodeView extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// popup_visible = (): Ray => { throw new NotImplementedError(); } +// set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } +// ident_at_cursor = (): Ray => { throw new NotImplementedError(); } +// insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } +// keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } +// set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } +// add_line_below = (text = str): Ray => { throw new NotImplementedError(); } +// } +// +// export class CodeCompletionModel extends Ray { +// __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } +// set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } +// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } +// rowCount = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class ChypDocument extends Ray { +// __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } +// confirm_close = (): Ray => { throw new NotImplementedError(); } +// add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } +// open = (file_name = str): Ray => { throw new NotImplementedError(); } +// save = (): Ray => { throw new NotImplementedError(); } +// save_as = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class Editor extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// title = (): Ray => { throw new NotImplementedError(); } +// reset_state = (): Ray => { throw new NotImplementedError(); } +// invalidate_text = (): Ray => { throw new NotImplementedError(); } +// next_part = (): Ray => { throw new NotImplementedError(); } +// jump_to_error = (): Ray => { throw new NotImplementedError(); } +// show_errors = (): Ray => { throw new NotImplementedError(); } +// show_at_cursor = (): Ray => { throw new NotImplementedError(); } +// next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } +// repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } +// update_state = (): Ray => { throw new NotImplementedError(); } +// import_at_cursor = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class CheckThread extends Ray { +// __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } +// run = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class ErrorListModel extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } +// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } +// headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } +// index = (row = int, column = int): Ray => { throw new NotImplementedError(); } +// columnCount = (): Ray => { throw new NotImplementedError(); } +// rowCount = (): Ray => { throw new NotImplementedError(); } +// parent = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class EItem extends Ray { +// __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } +// paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } +// } +// +// export class VItem extends Ray { +// __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } +// refresh = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class TItem extends Ray { +// __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } +// refresh = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class GraphScene extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } +// add_items = (): Ray => { throw new NotImplementedError(); } +// mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } +// mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } +// mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } +// } +// +// export class GraphView extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } +// } +// +// export class ChypHighlighter extends Ray { +// __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } +// set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } +// highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } +// } +// +// export class MainWindow extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// remove_empty_editor = (): Ray => { throw new NotImplementedError(); } +// update_file_name = (): Ray => { throw new NotImplementedError(); } +// tab_changed = (i = int): Ray => { throw new NotImplementedError(); } +// update_themes = (): Ray => { throw new NotImplementedError(); } +// recent_files = (): Ray => { throw new NotImplementedError(); } +// update_recent_files = (): Ray => { throw new NotImplementedError(); } +// add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } +// close_tab = (): Ray => { throw new NotImplementedError(); } +// new = (): Ray => { throw new NotImplementedError(); } +// open = (): Ray => { throw new NotImplementedError(); } +// save = (): Ray => { throw new NotImplementedError(); } +// save_as = (): Ray => { throw new NotImplementedError(); } +// undo = (): Ray => { throw new NotImplementedError(); } +// redo = (): Ray => { throw new NotImplementedError(); } +// show_errors = (): Ray => { throw new NotImplementedError(); } +// add_rewrite_step = (): Ray => { throw new NotImplementedError(); } +// repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } +// next_rewrite = (): Ray => { throw new NotImplementedError(); } +// next_part = (): Ray => { throw new NotImplementedError(); } +// previous_part = (): Ray => { throw new NotImplementedError(); } +// next_tab = (): Ray => { throw new NotImplementedError(); } +// previous_tab = (): Ray => { throw new NotImplementedError(); } +// goto_import = (): Ray => { throw new NotImplementedError(); } +// closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } +// build_menu = (): Ray => { throw new NotImplementedError(); } +// } +// +// // TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? +// export class Match extends Ray { +// +// get domain(): Graph { throw new NotImplementedError(); } +// get codomain(): Graph { throw new NotImplementedError(); } +// get vertex_map(): Ray { throw new NotImplementedError(); } +// get vertex_image(): Ray { throw new NotImplementedError(); } +// get edge_map(): Ray { throw new NotImplementedError(); } +// get edge_image(): Ray { throw new NotImplementedError(); } +// +// __init__ = (): Ray => { throw new NotImplementedError(); } +// __str__ = (): Ray => { +// // (f'\tVertex map: {str(self.vertex_map)}' +// // + f'\n\tEdge map: {str(self.edge_map)}') +// // TODO +// throw new NotImplementedError(); } +// +// // Implemented on Ray +// // TODO; doesnt copy the graphs at domain/codomain +// // copy = (): Ray => { throw new NotImplementedError(); } +// +// /** +// * Try to map `domain_vertex` to `codomain_vertex`. +// * +// * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. +// * +// * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. +// */ +// try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { +// +// // If the vertex is already mapped, only check the new mapping is consistent with the current match. +// if (this.vertex_map.includes(domain_vertex)) { +// log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) +// return this.vertex_map[domain_vertex] === codomain_vertex; +// } +// +// // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. +// // TODO: This should all be redundant, probably removed ... +// +// // Ensure the mapping preserves vertex type. +// if (domain_vertex.vtype !== codomain_vertex.vtype) { +// log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); +// +// return bool(False); +// } +// +// // Ensure the mapping preserves vertex size. +// if (domain_vertex.size !== codomain_vertex.size) { +// log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) +// return bool(False); +// } +// +// // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. +// if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { +// log('Vertex failed: codomain vertex is boundary but domain vertex is not.') +// return bool(False); +// } +// +// // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. +// if (this.vertex_image.includes(codomain_vertex)) { +// // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. +// if (!domain_vertex.is_boundary()) { +// log('Vertex failed: non-injective on interior vertex.') +// return bool(False); +// } +// +// // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. +// if (this.vertex_image.any(([mapped_vertex, image_vertex]) => +// image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! +// )) { +// log('Vertex failed: non-injective on interior vertex.') +// return bool(False); +// } +// +// return bool(False); +// } +// +// // If a new and consistent map is found, add it to the vertex map of this match. +// this.vertex_map[domain_vertex] = codomain_vertex +// this.vertex_image.add(codomain_vertex) +// +// // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. +// +// if (!domain_vertex.is_boundary()) { +// if (domain_vertex.in_edges.count() !== codomain_vertex.in_edges.count()) { +// log('Vertex failed: in_edges cannot satisfy gluing conditions.') +// return bool(False) +// } +// if (domain_vertex.out_edges.count() !== codomain_vertex.out_edges.count()) { +// log('Vertex failed: in_edges cannot satisfy gluing conditions.') +// return bool(False) +// } +// } +// +// // If a new consistent map is added that satisfies the gluing conditions, we are successful. +// log('Vertex success.') +// return bool(True); +// } +// +// try_add_edge = (domain_edge = int, codomain_edge = int): Ray => { throw new NotImplementedError(); } +// domain_neighbourhood_mapped = (vertex = int): Ray => { throw new NotImplementedError(); } +// map_scalars = (): Ray => { throw new NotImplementedError(); } +// more = (): Ray => { throw new NotImplementedError(); } +// is_total = (): Ray => { throw new NotImplementedError(); } +// is_surjective = (): Ray => { throw new NotImplementedError(); } +// is_injective = (): Ray => { throw new NotImplementedError(); } +// is_convex = (): Ray => { throw new NotImplementedError(); } +// +// /** +// * TODO Not implemented;; +// * # def cod_nhd_mapped(self, cod_v: int): +// * # """Returns True if nhd(cod_v) is the range of emap""" +// * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and +// * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) +// */ +// } +// +// export class Matches extends Ray { +// __init__ = (domain = Graph, codomain = Graph): Ray => { throw new NotImplementedError(); } +// __iter__ = (): Ray => { throw new NotImplementedError(); } +// __next__ = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class Rule extends Ray { +// get lhs(): Graph { throw new NotImplementedError(); } +// get rhs(): Graph { throw new NotImplementedError(); } +// +// /** +// * TODO: Put the name on each side of the rule, not the '-' hacky thing +// */ +// get name(): Ray { throw new NotImplementedError(); } +// get equiv(): Ray { throw new NotImplementedError(); } +// +// __init__ = (name = str(''), equiv = bool(True)): Ray => { +// // TODO: Maybe just move exception to a method on this thing +// +// if (this.lhs.domain !== this.rhs.domain) // TODO: !== +// throw new RuleError(`Inputs must match on LHS and RHS of rule (${this.rhs.domain} != ${this.lhs.domain})`); +// +// if (this.lhs.codomain !== this.rhs.codomain) +// throw new RuleError(`Outputs must match on LHS and RHS of rule (${this.rhs.codomain} != ${this.lhs.codomain})`) +// +// +// throw new NotImplementedError(); +// +// } +// +// copy = (): Ray => { throw new NotImplementedError(); } +// +// // TODO: Could put this on ray, generalize to swapping +// converse = (): Rule => { +// // TODO remove this hacky thing - just tries to us -a / a +// const name = this.name.as_string().startsWith('-') ? this.name.substring(1) : `-${this.name}`; +// +// const converse: Rule = this.copy().cast(); // TODO equiv=True? +// converse.name = name; +// +// // TODO: Wont work, we just should swap initial/terminal;\ +// //swap?? or change direction.. +// // const swap = converse.rhs; +// // converse.rhs = converse.lhs; +// // converse.lhs = swap; +// return converse; +// } +// +// /** +// * Returns True if boundary on lhs embeds injectively +// */ +// is_left_linear = (): Ray => { +// // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading +// return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() +// .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. +// } +// +// /** +// * Do double-pushout rewriting +// * +// * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. +// * @param match +// */ +// dpo = (match: Match): Ray => { +// // if (!this.is_left_linear()) +// // throw new NotImplementedError("Only left linear rules are supported for now") +// +// const rewritten_graph: Graph = match.codomain.copy(); +// +// // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? +// +// // Computes the push complement ?? (just the thing we're replacing right?) +// // TODO: Removes the match from the copy? +// this.lhs.edges().all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); +// +// const inputs = []; +// const outputs = []; +// +// this.lhs.vertices().all(rule_vertex => { +// const match_vertex = match.vertex_map[rule_vertex]; +// +// if (!this.lhs.is_boundary(rule_vertex)) { +// rewritten_graph.remove_vertex(match_vertex); +// return; +// } +// +// const rule_input = this.lhs.vertex_data(rule_vertex).in_indices; +// const rule_output = this.lhs.vertex_data(rule_vertex).out_indices; +// +// if (rule_input.count() === 1 && rule_output === 1) { +// const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); +// +// if (match_input.count() !== 1 && match_output.count() !== 1) +// throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); +// +// inputs[rule_vertex] = match_input[0]; +// outputs[rule_vertex] = match_output[0]; +// } else if (rule_input.count() > 1 || rule_output.count() > 1) { +// throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); +// } +// }) +// +// // Embed Rule.rhs into rewritten_graph +// const replacement = new Match(this.rhs, rewritten_graph); +// +// return replacement; +// } +// +// /** +// * Apply the given rewrite r to at match m and return the first result +// * +// * This is a convience wrapper for `dpo` for when the extra rewrite data isn't needed. +// */ +// rewrite = (match: Match): Graph => { +// // TODO: except StopIteration: +// // raise RuntimeError("Rewrite has no valid context") +// +// const result: Match = this.dpo(match).first().cast(); +// return result.codomain; +// } +// } +// +// export class RewriteState extends Ray { +// __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } +// check = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class State extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } +// part_at = (pos = int): Ray => { throw new NotImplementedError(); } +// var = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// num = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } +// type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } +// id = (items = list(Any)): Ray => { throw new NotImplementedError(); } +// id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } +// eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } +// le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } +// perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } +// size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } +// par = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// color = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// } +// +// export class Tactic extends Ray { +// __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } +// repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } +// error = (message = str): Ray => { throw new NotImplementedError(); } +// has_goal = (): Ray => { throw new NotImplementedError(); } +// global_rules = (): Ray => { throw new NotImplementedError(); } +// lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } +// add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } +// __lhs = (target = str): Ray => { throw new NotImplementedError(); } +// __rhs = (target = str): Ray => { throw new NotImplementedError(); } +// __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } +// __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } +// rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// validate_goal = (): Ray => { throw new NotImplementedError(); } +// lhs = (): Ray => { throw new NotImplementedError(); } +// rhs = (): Ray => { throw new NotImplementedError(); } +// lhs_size = (): Ray => { throw new NotImplementedError(); } +// rhs_size = (): Ray => { throw new NotImplementedError(); } +// highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } +// highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } +// __reset = (): Ray => { throw new NotImplementedError(); } +// next_rhs = (current = str): Ray => { throw new NotImplementedError(); } +// run_check = (): Ray => { throw new NotImplementedError(); } +// name = (): Ray => { throw new NotImplementedError(); } +// check = (): Ray => { throw new NotImplementedError(); } +// make_rhs = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class RuleTac extends Ray { +// name = (): Ray => { throw new NotImplementedError(); } +// make_rhs = (): Ray => { throw new NotImplementedError(); } +// check = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class SimpTac extends Ray { +// name = (): Ray => { throw new NotImplementedError(); } +// __prepare_rules = (): Ray => { throw new NotImplementedError(); } +// make_rhs = (): Ray => { throw new NotImplementedError(); } +// check = (): Ray => { throw new NotImplementedError(); } +// } +// diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 1e664d7..e1cbaea 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -1,11 +1,14 @@ import React, {useRef, useState} from "react"; import IEventListener from "../../js/react/IEventListener"; import {VisualizationCanvas} from "../../explorer/Visualization"; -import {add, AutoRenderedRay} from "../../explorer/OrbitMinesExplorer"; +import {add, AutoRay, AutoVertex} from "../../explorer/OrbitMinesExplorer"; import {Center} from "@react-three/drei"; import {useHotkeys} from "../../js/react/hooks/useHotkeys"; import {Ray} from "../../explorer/Ray"; +// TODO: Put the graphs setc at the top, invis lines, then draw them on hover, and maybe make surrounding stuff less visiable. +// TODO: make some function which uses a custom input like position of the interface as the thing which breaks equivalences - ignorances. Basically a custom "equivalency function" + const Interface = () => { const ref = useRef(); const hotkeys = useHotkeys(); @@ -14,10 +17,14 @@ const Interface = () => { const i = 20 * scale; const [selection, setSelection] = useState( - Ray.vertex().as_reference().o({ - position: [0, 0, 0], - scale - }) + Ray + .vertex().o({ position: [0, 0, 0], scale, color: 'orange' }) + .as_reference().o({ + position: [0, 0, 0], + scale, + rotation: [0, 0, Math.PI / 6 ], + color: '#FF5555' + }) ); const [rays, setRays] = useState([selection]); @@ -88,9 +95,13 @@ const Interface = () => { return <>
- + + + + {/**/} + {/**/} - {rays.map(ray => )} + {/*{rays.map(ray => )}*/} {/**/}
diff --git a/src/lib/paper/Paper.tsx b/src/lib/paper/Paper.tsx index ac80041..66b5cdf 100644 --- a/src/lib/paper/Paper.tsx +++ b/src/lib/paper/Paper.tsx @@ -1,22 +1,14 @@ import React from 'react'; import {Helmet} from "react-helmet"; import ExportablePaper, {PdfProps} from "./views/ExportablePaper"; -import {Children, renderable, value} from "../typescript/React"; +import {Children, value} from "../typescript/React"; import Browser from "./views/Browser"; import {useLocation, useSearchParams} from "react-router-dom"; import {ReferenceCounter, ReferenceProps, useCounter} from "./layout/Reference"; import {PaperHeader} from "./PaperContent"; import {Grid, Row} from "../layout/flexbox"; -import {Center} from "@react-three/drei"; -import {Continuation, Loop, RenderedRay, torus, Vertex} from "../../@orbitmines/explorer/OrbitMinesExplorer"; -import {length} from "../../@orbitmines/explorer/Ray"; -import { - CachedVisualizationCanvas, - CanvasContainer, - VisualizationCanvas -} from "../../@orbitmines/explorer/Visualization"; +import {CanvasContainer} from "../../@orbitmines/explorer/Visualization"; import JetBrainsMono from "../layout/font/fonts/JetBrainsMono/JetBrainsMono"; -import {ON_ORBITS} from "../../routes/papers/2023.OnOrbits"; import ORGANIZATIONS from "../organizations/ORGANIZATIONS"; import {PROFILES} from "../../profiles/profiles"; diff --git a/src/lib/paper/PaperContent.tsx b/src/lib/paper/PaperContent.tsx index c529e32..1e6d501 100644 --- a/src/lib/paper/PaperContent.tsx +++ b/src/lib/paper/PaperContent.tsx @@ -1,6 +1,6 @@ import {Col, Grid, Row} from "../layout/flexbox"; import {Divider, H1, H3, H4, Intent, Tag} from "@blueprintjs/core"; -import React, {useRef} from "react"; +import React from "react"; import {Children, Rendered} from "../typescript/React"; import {getFootnotes} from "./layout/Reference"; import Organization from "./layout/Organization"; @@ -9,12 +9,6 @@ import Link from "./layout/Link"; import ORGANIZATIONS from "../organizations/ORGANIZATIONS"; import Section from "./layout/Section"; import {PaperProps, PaperThumbnail} from "./Paper"; -import {PROFILES} from "../../profiles/profiles"; -import _ from "lodash"; -import {CachedVisualizationCanvas} from "../../@orbitmines/explorer/Visualization"; -import {Center} from "@react-three/drei"; -import {Continuation, RenderedRay, torus, Vertex} from "../../@orbitmines/explorer/OrbitMinesExplorer"; -import {length} from "../../@orbitmines/explorer/Ray"; import {useSearchParams} from "react-router-dom"; export const Title = ({children}: Children) => { From 6f59ac18e6125cb58c0ea64c3a71488bc3ef7fc3 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 18:53:01 +0100 Subject: [PATCH 027/138] 2024/02/09 - Experimenting with object proxy --- .../explorer/OrbitMinesExplorer.tsx | 4 +- src/@orbitmines/explorer/Ray.ts | 61 ++++-- src/@orbitmines/external/chyp/Chyp.ts | 199 ++++++++---------- src/@orbitmines/external/chyp/ChypCanvas.tsx | 35 +-- 4 files changed, 140 insertions(+), 159 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index c1776e0..a75738b 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -242,7 +242,7 @@ export const AutoRay = ( scale: 1.5, color: 'orange', ...defaults, - ...ray.o_ + ...ray.any.o }); // Move to a layer of abstraction above what is passed to us - this way we can start describing it. @@ -700,7 +700,7 @@ export const RenderedRay = ( } const render = - vertex.store.rendered = render; + vertex.any.rendered = render; return render; } diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 4d36162..14eb740 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -17,6 +17,8 @@ export enum RayType { export type ParameterlessFunction = () => T; export type Arbitrary = (...args: any[]) => T; +export type Constructor = new (...args: any[]) => T; +export type ParameterlessConstructor = new () => T; /** * https://en.wikipedia.org/wiki/Homoiconicity @@ -204,7 +206,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? equivalent = (other: Ray) => { throw new NotImplementedError(); } // TODO: Perhaps locally cache count?? - no way to ensure globally coherenct - count = (): Ray => { throw new NotImplementedError() } + get count(): Ray { throw new NotImplementedError() } // TODO; Could return the ignorant reference to both instances, or just the result., .. copy = (): Ray => { throw new NotImplementedError() } @@ -224,16 +226,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // // export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); - /** - * Cast to some JavaScript object - */ - cast = (): T => { throw new NotImplementedError(); }; - // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' - // map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } all = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } // filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } - clear = (): Ray => { throw new NotImplementedError(); } + get clear(): Ray { throw new NotImplementedError(); } // TODO: Generalize these functions to: // @@ -245,7 +242,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // [this.vertices().x.max(), this.edges().x.max()].max() // [this.vertices().x.min(), this.edges().x.max()].max() // TODO: Indicies not corresponding the the directionality defined, are probably on another abstraction layer described this way. More accurately, they're directly connected, and on a separate layer with more stuff in between... - index = (): Ray => { throw new NotImplementedError(); } + get index(): Ray { throw new NotImplementedError(); } + // TODO: Can probably generate these on the fly, or cache them automatically min = (_default: 0): Ray => { throw new NotImplementedError(); } max = (_default: 0): Ray => { throw new NotImplementedError(); } @@ -275,7 +273,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? *traverse(): Generator {} /** - * JavaScript, possible compilations + * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. */ // JS.AsyncGenerator async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } @@ -295,19 +293,36 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? toString = (): string => this.as_array().toString(); as_string = () => this.toString(); + as_int = (): number => { throw new NotImplementedError(); } + as_number = this.as_int; + /** - * Quick dirty compilation + * Move to a JavaScript object, which will handle any complexity of existing JavaScript objects, and allows one to abstract any values contained in the {vertex} to the usual JavaScript interface. - More usual to how one thinks about functions, ..., properties. */ - static dirty_store: { [label: string]: object } = {} - get store(): any { return Ray.dirty_store[this.label] ??= {} } - - // TODO: This is just any object implementation, nest the objects into a separte field, - o = (o: InterfaceOptions): Ray => { return this.___with('options', o); } - get o_(): InterfaceOptions { return this.store['options'] ?? {} } + get any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } + cast = (): T => this.proxy(); + + protected property = (property: string | symbol, _default?: any): any => this.any[property] ??= _default; // TODO: Can this be prettier?? + + protected _proxy: any; + protected _dirty_store: { [key: string | symbol]: object } = {} + protected proxy = (constructor?: ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: + return this._proxy ??= new Proxy(this, { + get(self: Ray, p: string | symbol, receiver: any): Arbitrary { + + // throw new NotImplementedError(); + // return self._dirty_store[p]; + return self.as_arbitrary(); + }, + set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { + // throw new NotImplementedError(); + self._dirty_store[p] = newValue; + + return true; + } - ___with = (key: string, any: any): Ray => { - this.store[key] = any; - return this; + // TODO: What do these other methods on Proxy do??? + }) as T; } debug = (c: { [label: string]: object | undefined }): object => { @@ -535,9 +550,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // return []; // } // - // includes(searchElement: Ray, fromIndex?: number): boolean { - // return false; - // } + includes(searchElement: Ray, fromIndex?: number): boolean { + return false; + } // // toReversed(): Ray[] { // return []; diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index c4a9633..2575e39 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1,6 +1,5 @@ -// import {Arbitrary, empty, JS, Ray} from "../../../explorer/Ray"; -// import { NotImplementedError } from "../../../explorer/errors/errors"; -// import {Option} from "../../../js/utils/Option"; +// import {JS, Ray} from "../../explorer/Ray"; +// import {NotImplementedError} from "../../explorer/errors/errors"; // // /** // * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. @@ -31,6 +30,10 @@ // * // * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph // */ +// /** +// * TODO: These coordinates used for inferences? +// * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" +// */ // // export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; // export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; @@ -64,6 +67,8 @@ // export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; // export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; // +// export const Color = (t1: Ray = str('')): Ray => { throw new NotImplementedError() }; +// // export class ValueError extends Error {} // // /** @@ -96,42 +101,25 @@ // * Data associated with a single vertex. // */ // export class VData extends Ray { -// // // The vertex type. -// get vtype(): Ray { throw new NotImplementedError(); } +// vtype = this.property('vtype', None); // -// /** -// * The register size (number of bundled parallel wires) of the vertex. -// * -// * TODO: Just a counter over a line -// */ -// get size(): Ray { throw new NotImplementedError(); } -// -// /** -// * Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). -// */ -// get infer_type(): Ray { throw new NotImplementedError(); } -// -// /** -// * Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). -// */ -// get infer_size(): Ray { throw new NotImplementedError(); } +// // The register size (number of bundled parallel wires) of the vertex. +// size = this.count; // Implemented on Ray.count // -// -// /** -// * TODO: These coordinates used for inferences? -// * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" -// */ +// // TODO: These infers will probably be removed? +// // Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). +// infer_type = this.property('infer_type', bool(False)) +// // Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). +// infer_size = this.property('infer_size', bool(False)) // // // x-coordinate at which to draw the vertex. -// get x(): Ray { throw new NotImplementedError(); } +// x = this.property('y', int(0)) // // y-coordinate at which to draw the vertex. -// get y(): Ray { throw new NotImplementedError(); } +// y = this.property('y', int(0)) // -// // TODO: Just some boolean -// get highlight(): Ray { throw new NotImplementedError(); } -// -// get value(): Ray { throw new NotImplementedError(); } +// highlight = this.property('highlight', bool(False)) +// value = this.property('value') // // /** // * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. @@ -148,20 +136,8 @@ // get in_indices(): Ray { return this.initial } // // get out_indices(): Ray { throw new NotImplementedError(); } // -// /** -// * Initialize a VData instance. -// */ -// __init__ = (): Ray => { -// this.highlight = bool(False); -// this.in_edges = set(int); -// this.out_edges = set(int); -// this.in_indices = set(int); -// this.out_indices = set(int); -// } -// -// -// is_input = (): Ray => this.in_indices.count() > 0; -// is_output = (): Ray => this.out_indices.count() > 0; +// is_input = (): Ray => this.in_indices.count.as_int() > 0; +// is_output = (): Ray => this.out_indices.count.as_int() > 0; // is_boundary = (): Ray => this.is_input() || this.is_output(); // // // TODO: Probably generalizable @@ -194,8 +170,8 @@ // vd.out_edges.add(e) // // # Wherever `w` occurs on the graph boundary, replace it with `v` -// self.set_inputs([v if x == w else x for x in self.inputs()]) -// self.set_outputs([v if x == w else x for x in self.outputs()]) +// self.set_inputs([v if x == w else x for x in self.inputs]) +// self.set_outputs([v if x == w else x for x in self.outputs]) // // # Remove references to `w` from the graph // self.remove_vertex(w) @@ -212,6 +188,10 @@ // // x=vd.x, y=vd.y, value=vd.value // // } +// +// // TODO: Shouldn't be here, this should be implemented on Ray if it's general enough +// get domain(): Ray { return JS.Iterable([this.vtype, this.size]) }; +// // } // // /** @@ -219,26 +199,22 @@ // */ // export class EData extends Ray { // +// get source() { return this.s }; +// get target() { return this.t }; +// // // TODO: this is just the initial frame // get s(): Ray { throw new NotImplementedError(); } -// // // TODO: this is just the terminal frame // get t(): Ray { throw new NotImplementedError(); } // -// -// get x(): Ray { throw new NotImplementedError(); } -// get y(): Ray { throw new NotImplementedError(); } -// get fg(): Ray { throw new NotImplementedError(); } -// get bg(): Ray { throw new NotImplementedError(); } -// get highlight(): Ray { throw new NotImplementedError(); } -// get hyper(): Ray { throw new NotImplementedError(); } -// get value(): Ray { throw new NotImplementedError(); } -// -// __init__ = (): Ray => { -// this.s = empty(); -// this.t = empty(); -// this.highlight = bool(False); -// } +// fg = this.property('bg', Color()); +// bg = this.property('bg', Color()); +// x = this.property('y', int(0)); +// // y-coordinate at which to draw the vertex. +// y = this.property('y', int(0)); +// highlight = this.property('highlight', bool(False)) +// hyper = this.property('value', bool(True)) +// value = this.property('value') // // __repr__ = (): Ray => { throw new NotImplementedError(); // // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' @@ -252,22 +228,12 @@ // * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. // * - Otherwise draw as a larger (size 2) box. // */ -// box_size = (): Ray => (this.s.count() <= 1 && this.t.count() <= 1) ? 1 : 2; +// box_size = (): Ray => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); // -// toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL -// -// get source() { return this.s }; -// get target() { return this.t }; -// -// // TODO: Shouldn't be here, this should either be implemented on Ray if it's general enough, of just remain here as an artifact -// protected ___domain = (ray: Ray) => ray.map(_ => { -// const vertex: VData = _.cast(); -// return [vertex.vtype, vertex.size]; -// }); -// -// domain = (): Ray => this.___domain(this.source); -// codomain = (): Ray => this.___domain(this.target); +// domain = (): Ray => this.source.cast().domain; +// codomain = (): Ray => this.target.cast().domain; // +// toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL // } // // /** @@ -286,18 +252,17 @@ // */ // export class Graph extends Ray { // -// // Mapping from integer identifiers of each vertex to its data. -// get vdata(): Ray { throw new NotImplementedError(); } -// // Mapping from integer identifiers of each hyperedge to its data. -// get edata(): Ray { throw new NotImplementedError(); } -// -// // TODO: Can probably generate these on the fly, or cache them automatically // get vindex(): Ray { return this.vdata.index.max(0); } // get eindex(): Ray { return this.edata.index.max(0); } // +// // Mapping from integer identifiers of each vertex to its data. +// vdata = this.property('vertices'); +// // Mapping from integer identifiers of each hyperedge to its data. +// edata = this.property('edges'); +// // // TODO .keys -// vertices = (): Ray => this.vdata; -// edges = (): Ray => this.edata; +// vertices = this.property('vertices'); +// edges = this.property('edges'); // // // TODO: Shouldn't be here, this should either be implemented on Ray if it's general enough, of just remain here as an artifact // protected ___domain = (ray: Ray) => ray.map(_ => { @@ -311,14 +276,14 @@ // * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. // */ // // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. -// get domain(): Ray { return this.___domain(this.inputs()) }; +// get domain(): Ray { return this.___domain(this.inputs) }; // // /** // * Return the domain of the graph. // * // * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. // */ -// get codomain(): Ray { return this.___domain(this.outputs()) }; +// get codomain(): Ray { return this.___domain(this.outputs) }; // // vertex_data = (v = int): VData => this.vertices().at(v).cast(); // edge_data = (e = int): EData => this.edges().at(e).cast(); @@ -380,12 +345,12 @@ // // TODO: as delegation // // if (strict) { -// if (this.vertex_data(v).in_edges.count() > 0 || this.vertex_data(v).out_edges > 0) { +// if (this.vertex_data(v).in_edges.count.as_int() > 0 || this.vertex_data(v).out_edges > 0) { // throw new ValueError('Attempting to remove vertex with adjacent' // + 'edges while strict == True.'); // } // -// if (this.inputs().includes(v) || this.outputs.includes(v)) { +// if (this.inputs.includes(v) || this.outputs.includes(v)) { // throw new ValueError('Attempting to remove boundary vertex while' // + 'strict == True.'); // @@ -415,7 +380,7 @@ // * @param inp The list of vertex integer identifiers of the appended inputs. // */ // add_inputs = (inp = list(int)): Ray => { -// this.inputs().continues_with(inp); // TODO: Perhaps splat +// this.inputs.continues_with(inp); // TODO: Perhaps splat // } // /** // * Append `outp` to the outputs of the graph. @@ -423,7 +388,7 @@ // * @param outp The list of vertex integer identifiers of the appended outputs. // */ // add_outputs = (outp = list(int)): Ray => { -// this.outputs().continues_with(outp); // TODO: Perhaps splat +// this.outputs.continues_with(outp); // TODO: Perhaps splat // } // // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) // @@ -451,10 +416,10 @@ // * All these are just delegations from some Vertex/Edge structure. // */ // // .vertices -// num_vertices = (): Ray => this.vertices().count(); +// num_vertices = (): Ray => this.vertices().count.as_int(); // // // .edges -// num_edges = (): Ray => this.edges().count(); +// num_edges = (): Ray => this.edges().count.as_int(); // // // .vertex_data // is_input = (v = int): Ray => this.vertex_data(v).is_input(); @@ -514,7 +479,7 @@ // // TODO: It's just a duplicated process for vertex/edge since their definition is separataed // // // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. -// // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs()]) +// // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs]) // // TODO: Basically a copy, and replace this one vertex // // // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. @@ -566,19 +531,19 @@ // // const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] // -// tensor.initial.y -= -// tensor.initial.y.max(); // max_self +// tensor.initial.any.y -= +// tensor.initial.any.y.max(); // max_self // -// tensor.terminal.y -= -// (layout ? tensor.terminal.y.min() : 0) + 1; // min_other TODO: Why + 1 ? +// tensor.terminal.any.y -= +// (layout ? tensor.terminal.any.y.min() : 0) + 1; // min_other TODO: Why + 1 ? // // /** -// * # self.set_inputs(self.inputs() + [vmap[v] for v in other.inputs()]) -// * # self.set_outputs(self.outputs() + [vmap[v] for v in other.outputs()]) +// * # self.set_inputs(self.inputs + [vmap[v] for v in other.inputs]) +// * # self.set_outputs(self.outputs + [vmap[v] for v in other.outputs]) // * // * # Add the inputs and outputs of the other graph to this one. -// * self.add_inputs([vmap[v] for v in other.inputs()]) -// * self.add_outputs([vmap[v] for v in other.outputs()]) +// * self.add_inputs([vmap[v] for v in other.inputs]) +// * self.add_outputs([vmap[v] for v in other.outputs]) // */ // // TODO: Add equivalence/reference on the inputs/output extremes. // } @@ -604,7 +569,7 @@ // // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs // // { -// if (compose.initial.count() !== compose.terminal.count()) +// if (compose.initial.count.as_int() !== compose.terminal.count.as_int()) // throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed // // /** @@ -634,23 +599,23 @@ // // // TODO: Again, recursively going through everything defined on the initial side (outputs) // // Shift all vertices and edges of this graph below the x-axis. -// compose.initial.x -= -// compose.initial.x.max(); // max_self +// compose.initial.any.x -= +// compose.initial.any.x.max(); // max_self // // // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] -// compose.terminal.x -= -// compose.terminal.x.min(); // min_other +// compose.terminal.any.x -= +// compose.terminal.any.x.min(); // min_other // // // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. // /** -// * plug1 = self.outputs() -// * plug2 = [vmap[v] for v in other.inputs()] +// * plug1 = self.outputs +// * plug2 = [vmap[v] for v in other.inputs] // * // * if len(plug1) != len(plug2): // * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' // * + f'outputs into one with {len(plug2)} inputs') // * -// * self.set_outputs([vmap[v] for v in other.outputs()]) +// * self.set_outputs([vmap[v] for v in other.outputs]) // */ // // // [outputs to inputs] @@ -844,9 +809,9 @@ // perm = (p = list(int), domain: Ray, _default: VData) => { // // const graph = new Graph(); -// const num_wires = p.count(); +// const num_wires = p.count.as_int(); // -// if (num_wires !== domain.count()) +// if (num_wires !== domain.count.as_int()) // throw new GraphError(`Domain ${domain} does not match length of permutation.`) // // // TODO use ___map_domain @@ -1134,11 +1099,11 @@ // // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. // // if (!domain_vertex.is_boundary()) { -// if (domain_vertex.in_edges.count() !== codomain_vertex.in_edges.count()) { +// if (domain_vertex.in_edges.count.as_int() !== codomain_vertex.in_edges.count.as_int()) { // log('Vertex failed: in_edges cannot satisfy gluing conditions.') // return bool(False) // } -// if (domain_vertex.out_edges.count() !== codomain_vertex.out_edges.count()) { +// if (domain_vertex.out_edges.count.as_int() !== codomain_vertex.out_edges.count.as_int()) { // log('Vertex failed: in_edges cannot satisfy gluing conditions.') // return bool(False) // } @@ -1256,15 +1221,15 @@ // const rule_input = this.lhs.vertex_data(rule_vertex).in_indices; // const rule_output = this.lhs.vertex_data(rule_vertex).out_indices; // -// if (rule_input.count() === 1 && rule_output === 1) { +// if (rule_input.count.as_int() === 1 && rule_output === 1) { // const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); // -// if (match_input.count() !== 1 && match_output.count() !== 1) +// if (match_input.count.as_int() !== 1 && match_output.count.as_int() !== 1) // throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); // // inputs[rule_vertex] = match_input[0]; // outputs[rule_vertex] = match_output[0]; -// } else if (rule_input.count() > 1 || rule_output.count() > 1) { +// } else if (rule_input.count.as_int() > 1 || rule_output.count.as_int() > 1) { // throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); // } // }) diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index e1cbaea..44281ea 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -8,6 +8,7 @@ import {Ray} from "../../explorer/Ray"; // TODO: Put the graphs setc at the top, invis lines, then draw them on hover, and maybe make surrounding stuff less visiable. // TODO: make some function which uses a custom input like position of the interface as the thing which breaks equivalences - ignorances. Basically a custom "equivalency function" +// TODO; Key to output javascript compilation targets in console, array, .. etc. const Interface = () => { const ref = useRef(); @@ -18,8 +19,8 @@ const Interface = () => { const [selection, setSelection] = useState( Ray - .vertex().o({ position: [0, 0, 0], scale, color: 'orange' }) - .as_reference().o({ + .vertex().any.o({ position: [0, 0, 0], scale, color: 'orange' }) + .as_reference().any.o({ position: [0, 0, 0], scale, rotation: [0, 0, Math.PI / 6 ], @@ -33,8 +34,8 @@ const Interface = () => { { combo: "arrowright", global: true, label: "", onKeyDown: () => { - const next = Ray.js("A").as_reference().o({ - position: add(selection.o_.position ?? [0, 0, 0], [i * 2, 0, 0]), + const next = Ray.js("A").as_reference().any.o({ + position: add(selection.any.o.position ?? [0, 0, 0], [i * 2, 0, 0]), scale }); setSelection(next); @@ -65,23 +66,23 @@ const Interface = () => { setRays(rays.flatMap(ray => [ ray, - Ray.js("A").as_reference().o({ - ...ray.o_, - position: add(ray.o_.position ?? [0, 0, 0], [0, i * 2, 0]) + Ray.js("A").as_reference().any.o({ + ...ray.any.o, + position: add(ray.any.o.position ?? [0, 0, 0], [0, i * 2, 0]) }), - Ray.js("A").as_reference().o({ - ...ray.o_, - position: ray.o_.position, + Ray.js("A").as_reference().any.o({ + ...ray.any.o, + position: ray.any.o.position, rotation: [0, 0, Math.PI / 2] }), - Ray.js("A").as_reference().o({ - ...ray.o_, - position: add(ray.o_.position ?? [0, 0, 0], [0, i * 2, 0]), + Ray.js("A").as_reference().any.o({ + ...ray.any.o, + position: add(ray.any.o.position ?? [0, 0, 0], [0, i * 2, 0]), rotation: [0, 0, Math.PI / 2] }) ])); - selection.o({...selection.o_, position: add(selection.o_.position ?? [0, 0, 0], [0, i * 2, 0])}) + selection.any.o({...selection.any.o, position: add(selection.any.o.position ?? [0, 0, 0], [0, i * 2, 0])}) setSelection(selection) // selection.continues_with( @@ -98,10 +99,10 @@ const Interface = () => { - {/**/} - {/**/} + {/**/} + {/**/} - {/*{rays.map(ray => )}*/} + {/*{rays.map(ray => )}*/} {/**/}
From a762e89d21853a57d2f848be8e3f01d093be69c0 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 19:10:23 +0100 Subject: [PATCH 028/138] 2024/02/09 - Experimenting with object proxy & JS.Object --- .../explorer/OrbitMinesExplorer.tsx | 2 +- src/@orbitmines/explorer/Ray.spec.ts | 31 +++++++++++++++- src/@orbitmines/explorer/Ray.ts | 18 ++++++---- src/@orbitmines/external/chyp/ChypCanvas.tsx | 36 ++++++++++--------- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index a75738b..b5598c4 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -242,7 +242,7 @@ export const AutoRay = ( scale: 1.5, color: 'orange', ...defaults, - ...ray.any.o + ...ray.o }); // Move to a layer of abstraction above what is passed to us - this way we can start describing it. diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 6ace225..d1b9d94 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -1,7 +1,36 @@ -import {Ray, RayType} from "./Ray"; +import {JS, Ray, RayType} from "./Ray"; import {PreventsImplementationBug} from "./errors/errors"; +describe("JS", () => { + test(".Object", () => { + const ray = JS.Object({ + a: 'b', + position: [0, 1, 2], + func: () => 'c' + }); + + expect(ray.any.a).toBe('b'); + expect(ray.any.test).toBe(undefined); + expect(() => ray.any.undefinedFunction()).toThrow(); + expect(ray.any.position).toEqual([0, 1, 2]); + expect(ray.any.func()).toBe('c'); + }) +}); describe("Ray", () => { + test(".o", () => { + const ray = Ray.vertex().o({ + a: 'b', + position: [0, 1, 2], + func: () => 'c' + }); + + expect(ray.any.a).toBe('b'); + expect(ray.any.test).toBe(undefined); + expect(() => ray.any.undefinedFunction()).toThrow(); + expect(ray.any.position).toEqual([0, 1, 2]); + expect(ray.any.func()).toBe('c'); + }) + test(".vertex.#", () => { /** [--|--] */ const vertex = Ray.vertex().as_reference(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 14eb740..9782a23 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -302,17 +302,25 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? get any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } cast = (): T => this.proxy(); + /** + * Used for chaining JavaScript-provided properties + */ + o = (object: { [key: string | symbol]: any }): Ray => { + _.keys(object).forEach(key => this.any[key] = object[key]); // TODO: Can be prettier, TODO: map to Ray equivalents and add to vertices.. + return this; + } + protected property = (property: string | symbol, _default?: any): any => this.any[property] ??= _default; // TODO: Can this be prettier?? protected _proxy: any; protected _dirty_store: { [key: string | symbol]: object } = {} protected proxy = (constructor?: ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: return this._proxy ??= new Proxy(this, { - get(self: Ray, p: string | symbol, receiver: any): Arbitrary { + get(self: Ray, p: string | symbol, receiver: any): any { // throw new NotImplementedError(); - // return self._dirty_store[p]; - return self.as_arbitrary(); + return self._dirty_store[p]; + // return self.as_arbitrary(); }, set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { // throw new NotImplementedError(); @@ -678,9 +686,7 @@ export namespace JS { throw new NotImplementedError(); } - export const Object = (object: object): Ray => { - throw new NotImplementedError(); - } + export const Object = (object: object): Ray => Ray.vertex().o(object); export const Any = (any: any): Ray => { if (any === null || any === undefined) return JS.Any(any); diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 44281ea..57b7157 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -19,8 +19,8 @@ const Interface = () => { const [selection, setSelection] = useState( Ray - .vertex().any.o({ position: [0, 0, 0], scale, color: 'orange' }) - .as_reference().any.o({ + .vertex().o({ position: [0, 0, 0], scale, color: 'orange' }) + .as_reference().o({ position: [0, 0, 0], scale, rotation: [0, 0, Math.PI / 6 ], @@ -28,14 +28,16 @@ const Interface = () => { }) ); + console.log(Ray.vertex().o({ color: 'red'}).any.color) + const [rays, setRays] = useState([selection]); hotkeys.set(...[ { combo: "arrowright", global: true, label: "", onKeyDown: () => { - const next = Ray.js("A").as_reference().any.o({ - position: add(selection.any.o.position ?? [0, 0, 0], [i * 2, 0, 0]), + const next = Ray.js("A").as_reference().o({ + position: add(selection.any.position ?? [0, 0, 0], [i * 2, 0, 0]), scale }); setSelection(next); @@ -66,23 +68,23 @@ const Interface = () => { setRays(rays.flatMap(ray => [ ray, - Ray.js("A").as_reference().any.o({ - ...ray.any.o, - position: add(ray.any.o.position ?? [0, 0, 0], [0, i * 2, 0]) + Ray.js("A").as_reference().o({ + ...ray.o, + position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]) }), - Ray.js("A").as_reference().any.o({ - ...ray.any.o, - position: ray.any.o.position, + Ray.js("A").as_reference().o({ + ...ray.o, + position: ray.any.position, rotation: [0, 0, Math.PI / 2] }), - Ray.js("A").as_reference().any.o({ - ...ray.any.o, - position: add(ray.any.o.position ?? [0, 0, 0], [0, i * 2, 0]), + Ray.js("A").as_reference().o({ + ...ray.o, + position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]), rotation: [0, 0, Math.PI / 2] }) ])); - selection.any.o({...selection.any.o, position: add(selection.any.o.position ?? [0, 0, 0], [0, i * 2, 0])}) + selection.o({...selection.o, position: add(selection.any.position ?? [0, 0, 0], [0, i * 2, 0])}) setSelection(selection) // selection.continues_with( @@ -99,10 +101,10 @@ const Interface = () => { - {/**/} - {/**/} + {/**/} + {/**/} - {/*{rays.map(ray => )}*/} + {/*{rays.map(ray => )}*/} {/**/}
From 558dfff35fd21dcdb57a257e0be41802f2b8986f Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 19:18:43 +0100 Subject: [PATCH 029/138] 2024/02/09 - GitHub tests --- .github/workflows/test.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..20be79e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,14 @@ +name: Tests + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v3 + - run: npm install + - run: npm run test -- --watchAll=false \ No newline at end of file From e2fc773eaa85c3de514c7efa26fbfd849063288b Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 20:06:58 +0100 Subject: [PATCH 030/138] 2024/02/09 - Move everything into a Ray --- .../explorer/OrbitMinesExplorer.tsx | 18 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 180 ++++++++++-------- 2 files changed, 109 insertions(+), 89 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index b5598c4..5883403 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -236,14 +236,16 @@ export const AutoRay = ( ) => { compiler ??= new TempCompiler(); - const o = (ray: Ray, defaults: InterfaceOptions = {}): Required => ({ - position: [0, 0, 0], - rotation: [0, 0, 0], - scale: 1.5, - color: 'orange', - ...defaults, - ...ray.o - }); + + const o = (ray: Ray, defaults: InterfaceOptions = {}): Required => { + const { + position = defaults.position ?? [0, 0, 0], + rotation = defaults.rotation ?? [0, 0, 0], + scale = defaults.scale ?? 1.5, + color = defaults.color ?? 'orange' + } = ray.any; + return ({ position, rotation, scale, color, }) + }; // Move to a layer of abstraction above what is passed to us - this way we can start describing it. const ref = { // TODO; This general pattern is probably worth abstracting somewhere. diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 57b7157..3354fe6 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -1,10 +1,12 @@ import React, {useRef, useState} from "react"; import IEventListener from "../../js/react/IEventListener"; import {VisualizationCanvas} from "../../explorer/Visualization"; -import {add, AutoRay, AutoVertex} from "../../explorer/OrbitMinesExplorer"; +import {add, AutoRay, AutoVertex, InterfaceOptions} from "../../explorer/OrbitMinesExplorer"; import {Center} from "@react-three/drei"; import {useHotkeys} from "../../js/react/hooks/useHotkeys"; import {Ray} from "../../explorer/Ray"; +import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; +import {keys} from "lodash"; // TODO: Put the graphs setc at the top, invis lines, then draw them on hover, and maybe make surrounding stuff less visiable. // TODO: make some function which uses a custom input like position of the interface as the thing which breaks equivalences - ignorances. Basically a custom "equivalency function" @@ -12,99 +14,115 @@ import {Ray} from "../../explorer/Ray"; const Interface = () => { const ref = useRef(); - const hotkeys = useHotkeys(); + const hotkeyConfig = useHotkeys(); const scale = 1.5; const i = 20 * scale; - const [selection, setSelection] = useState( - Ray + const cursor: InterfaceOptions = { + scale, + rotation: [0, 0, Math.PI / 6 ], + color: '#FF5555' + }; + + const [Chyp] = useState(Ray.vertex().o({ + selection: Ray .vertex().o({ position: [0, 0, 0], scale, color: 'orange' }) .as_reference().o({ position: [0, 0, 0], - scale, - rotation: [0, 0, Math.PI / 6 ], - color: '#FF5555' - }) - ); - - console.log(Ray.vertex().o({ color: 'red'}).any.color) - - const [rays, setRays] = useState([selection]); - - hotkeys.set(...[ - { - combo: "arrowright", global: true, label: "", onKeyDown: () => { - - const next = Ray.js("A").as_reference().o({ - position: add(selection.any.position ?? [0, 0, 0], [i * 2, 0, 0]), - scale - }); - setSelection(next); - setRays([...rays, next]); - - // selection.continues_with( - - // ); - - console.log(rays); - } - }, - { - combo: "arrowleft", global: true, label: "", onKeyDown: () => { - - rays.pop(); - setSelection(rays[rays.length - 1]); - - // selection.continues_with( - - // ); - - console.log(rays); - } - }, - { - combo: "arrowup", global: true, label: "", onKeyDown: () => { - - setRays(rays.flatMap(ray => [ - ray, - Ray.js("A").as_reference().o({ - ...ray.o, - position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]) - }), - Ray.js("A").as_reference().o({ - ...ray.o, - position: ray.any.position, - rotation: [0, 0, Math.PI / 2] - }), - Ray.js("A").as_reference().o({ - ...ray.o, - position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]), - rotation: [0, 0, Math.PI / 2] - }) - ])); - - selection.o({...selection.o, position: add(selection.any.position ?? [0, 0, 0], [0, i * 2, 0])}) - setSelection(selection) - - // selection.continues_with( - - // ); - - console.log(rays); - } - } - ]); + ...cursor + }), + rays: [] as Ray[], + controls: Ray.vertex().o({ + hotkeys: [ { + combo: "arrowright", global: true, label: "", onKeyDown: () => { + const { selection, rays } = Chyp.any; + + const next = Ray.js("A").as_reference().o({ + position: add(selection.any.position ?? [0, 0, 0], [i * 2, 0, 0]), + scale + }); + + Chyp.any.selection = next; + Chyp.any.rays = [...rays, next] + + // selection.continues_with( + + // ); + } + }, + { + combo: "arrowleft", global: true, label: "", onKeyDown: () => { + const { selection, rays } = Chyp.any; + + rays.pop(); + Chyp.any.selection = rays[rays.length - 1]; + + // selection.continues_with( + + // ); + + } + }, + { + combo: "arrowup", global: true, label: "", onKeyDown: () => { + const { selection, rays } = Chyp.any; + + Chyp.any.rays = rays.flatMap((ray: Ray) => [ + ray, + // Ray.js("A").as_reference().o({ + // // ...ray.o, + // position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]) + // }), + // Ray.js("A").as_reference().o({ + // // ...ray.o, + // position: ray.any.position, + // rotation: [0, 0, Math.PI / 2] + // }), + // Ray.js("A").as_reference().o({ + // // ...ray.o, + // position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]), + // rotation: [0, 0, Math.PI / 2] + // }) + ]); + + // Chyp.any.selection = Chyp; + + // selection.o({...selection.o, position: add(selection.any.position ?? [0, 0, 0], [0, i * 2, 0])}) + + // selection.continues_with( + + // ); + } + }] as HotkeyConfig[] + }) + })); + + const { selection, controls, rays } = Chyp.any; + const { hotkeys } = controls.any; + + hotkeyConfig.set(...hotkeys); + + const Rendered = ({ ray, ...options }: { ray: Ray } & InterfaceOptions) => { + const { position = options.position, rotation = options.rotation, scale = options.scale, color = options.color } = ray.any; + return ; + } + return <>
- - - + {/**/} + {/**/} + {/**/} + + {/**/} + {/**/} {/**/} + + - {/*{rays.map(ray => )}*/} + {rays.map((ray: Ray) => )} {/**/}
From cb0e45e3e05ca16b9e0c7f3ed7be53cbfa95d10d Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 20:21:27 +0100 Subject: [PATCH 031/138] 2024/02/09 - Move everything into a Ray --- src/@orbitmines/external/chyp/ChypCanvas.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 3354fe6..47c92b9 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -25,6 +25,9 @@ const Interface = () => { color: '#FF5555' }; + // TODO: Direct call to rerender on change, now there's lag + + const [Chyp] = useState(Ray.vertex().o({ selection: Ray .vertex().o({ position: [0, 0, 0], scale, color: 'orange' }) @@ -42,6 +45,10 @@ const Interface = () => { position: add(selection.any.position ?? [0, 0, 0], [i * 2, 0, 0]), scale }); + // const next2 = Ray.js("A").as_reference().o({ + // position: add(selection.any.position ?? [0, 0, 0], [i * 2, -30, 0]), + // scale + // }); Chyp.any.selection = next; Chyp.any.rays = [...rays, next] @@ -55,7 +62,16 @@ const Interface = () => { combo: "arrowleft", global: true, label: "", onKeyDown: () => { const { selection, rays } = Chyp.any; + if (rays.length === 0) + return; + rays.pop(); + + if (rays.length === 0) { + Chyp.any.selection.any.position = [0, 0, 0] + return; + } + Chyp.any.selection = rays[rays.length - 1]; // selection.continues_with( From 161eba12bd2d6cc98178b8fc8ed23336cf33659c Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 23:08:26 +0100 Subject: [PATCH 032/138] 2024/02/09 - Trying some debug mode options --- .../explorer/OrbitMinesExplorer.tsx | 6 +- src/@orbitmines/explorer/Ray.spec.ts | 10 ++ src/@orbitmines/explorer/Ray.ts | 78 +++++++----- src/@orbitmines/external/chyp/Chyp.ts | 10 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 117 ++++++++++++++++-- 5 files changed, 170 insertions(+), 51 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index 5883403..1a19153 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -344,13 +344,13 @@ export const AutoVertex = (ray: Omit & InterfaceOptions & { {children}
} -const _Continuation = ({ color = torus.color, ...options }: InterfaceOptions) => +export const _Continuation = ({ color = torus.color, ...options }: InterfaceOptions) => -const _Vertex = ({ color = circle.color, ...options }: any) => +export const _Vertex = ({ color = circle.color, ...options }: any) => { const next = selection.continues_with( - Ray.js("A").as_reference() + Ray.vertex().as_reference() ); setSelection(next) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index d1b9d94..8e3db38 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -17,6 +17,16 @@ describe("JS", () => { }) }); describe("Ray", () => { + test(".vertex.#.debug", () => { + const a = Ray.vertex().as_reference(); + const b = Ray.vertex().as_reference(); + a.continues_with(b); + + const debug = {}; + a.debug(debug); + + expect(debug).toEqual('') + }) test(".o", () => { const ray = Ray.vertex().o({ a: 'b', diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 9782a23..7ab6c9f 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -31,6 +31,19 @@ export interface PossiblyHomoiconic> { export interface AbstractDirectionality { initial: Arbitrary, vertex: Arbitrary, terminal: Arbitrary } +export type DebugResult = { [label: string]: DebugRay } +export type DebugRay = { + label: string, + initial: string, + vertex: string, + terminal: string, + is_initial: boolean, + is_vertex: boolean, + is_terminal: boolean, + type: RayType, + _dirty_store: any +} + /** * JavaScript wrapper for a mutable value. It is important to realize that this is merely some simple JavaScript abstraction, and anything is assumed to be inherently mutable. * @@ -60,9 +73,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // Array // Dict { - - js: Arbitrary - // TODO: Could make a case that setting the terminal is more of a map, defaulting/first checking the terminal before additional functionality is mapped over that. protected _initial: Arbitrary; get initial(): Ray { return this._initial(); } set initial(initial: Arbitrary) { this._initial = initial; } @@ -84,13 +94,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? [index: number]: Ray; - constructor({ initial, vertex, terminal, - js, - }: { js?: Arbitrary } & Partial> = {}) { + constructor({ initial, vertex, terminal, }: Partial> = {}) { this._initial = initial ?? Ray.None; this._vertex = vertex ?? this.self_reference; // TODO: None, could also self-reference the ray on which it's defining to be None. Now it's just an ignorant loop. this._terminal = terminal ?? Ray.None; - this.js = js ?? Ray.None; } /** [ |-?] */ is_initial = (): boolean => this.is_some() && this.self.initial.is_none(); @@ -134,18 +141,17 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // new Ray({ initial: this.as_arbitrary(), vertex: () => this.terminal, js: () => 'terminal ref' }); // TODO: These fields as DEBUG /** [ ] */ const vertex = Ray.None(); - /** [-- ] */ vertex.initial = new Ray({ vertex: Ray.None, terminal: vertex.as_arbitrary(), js: () => 'initial ref' }).as_arbitrary(); + /** [-- ] */ vertex.initial = new Ray({ vertex: Ray.None, terminal: vertex.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); /** [ ? ] */ vertex.vertex = value; - /** [ --] */ vertex.terminal = new Ray({ vertex: Ray.None, initial: vertex.as_arbitrary(), js: () => 'terminal ref' }).as_arbitrary() + /** [ --] */ vertex.terminal = new Ray({ vertex: Ray.None, initial: vertex.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() /** [--?--] */ return vertex; } - static js = (value: any) => { const vertex = Ray.vertex(); vertex.js = () => value; return vertex; } static size = (of: number, value: any = undefined): Ray => { let current = Ray.vertex().as_reference(); // TODO; This sort of thing should be lazy for (let i = 0; i < of; i++) { - current = current.continues_with(Ray.js(value).as_reference()); + current = current.continues_with(Ray.vertex(JS.Any(value).as_arbitrary()).as_reference()); } return current; @@ -183,18 +189,17 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return next_vertex.as_reference(); // TODO: Generally, return something which knows where all continuations are. } - // this.self.terminal = next_vertex.initial; equivalence# - - // switch (b.type) { - // case RayType.REFERENCE: - // break; - // case RayType.INITIAL: - // break; - // case RayType.TERMINAL: - // break; - // case RayType.VERTEX: - // break; - // } + switch (b.type) { + case RayType.REFERENCE: + case RayType.INITIAL: + case RayType.TERMINAL: { + throw new PreventsImplementationBug(); + } + case RayType.VERTEX: { + this.self.terminal.equivalent(b.self.initial); + break; + } + } return next_vertex.as_reference(); } @@ -203,7 +208,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO NEEDS TO CHECK IF THERE'S SOME INITIAL DEFIEND ; for defining if it has halted - equivalent = (other: Ray) => { throw new NotImplementedError(); } + protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother + this.self = b.as_arbitrary(); + b.self = this.as_arbitrary(); + } // TODO: Perhaps locally cache count?? - no way to ensure globally coherenct get count(): Ray { throw new NotImplementedError() } @@ -333,12 +341,12 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }) as T; } - debug = (c: { [label: string]: object | undefined }): object => { + debug = (c: DebugResult): DebugRay => { if (c[this.label] !== undefined) return c[this.label]!; const of = (ray: Ray): string => { - if (ray.is_none()) return 'None'; + if (ray.as_reference().is_none()) return 'None'; ray.debug(c); return ray.label; @@ -347,10 +355,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? const obj: any = { label: this.label }; c[this.label] = obj; + obj.label = this.label; obj.initial = of(this.initial); obj.vertex = of(this.vertex); obj.terminal = of(this.terminal); obj.type = this.as_reference().type; + obj.is_initial = this.as_reference().is_initial(); + obj.is_vertex = this.as_reference().is_vertex(); + obj.is_terminal = this.as_reference().is_terminal(); + obj._dirty_store = this._dirty_store; return obj; } @@ -422,7 +435,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (this.__label !== undefined) return this.__label; - return this.__label = `"${Ray._label++} (${this.js()?.toString() ?? '?'})})"`; + return this.__label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; } // length: number; @@ -616,8 +629,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? export namespace JS { export const Boolean = (boolean: boolean): Ray => { // |-false->-true-| (could of course also be reversed) - const _false = Ray.js(false); - const _true = Ray.js(true); + const _false = Ray.vertex().o({ js: false }); + const _true = Ray.vertex().o({ js: true }); _false.continues_with(_true); return (boolean ? _true : _false).as_reference(); @@ -650,12 +663,11 @@ export namespace JS { } const current: Ray = new Ray({ - js: () => iterator_result.value, // initial: () => new Ray(), initial: () => initial, vertex: () => JS.Any(iterator_result.value), terminal: () => next(current) - }); + }).o({js: iterator_result.value}); // initial.continues_with(() => current.as_reference()); if (initial.is_some()) @@ -664,7 +676,7 @@ export namespace JS { return current; } - const ray_iterator = new Ray({ js: () => iterator}); + const ray_iterator = Ray.None().o({ js: iterator }); ray_iterator.terminal = () => next(ray_iterator); // This indicates we're passing a reference, since traversal logic will be defined at its vertex - what it's defining. @@ -698,7 +710,7 @@ export namespace JS { // TODO // return JS.Any(any); - return Ray.js(any); + return Ray.vertex().o({js: any}); } export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index 2575e39..07f147d 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -264,26 +264,20 @@ // vertices = this.property('vertices'); // edges = this.property('edges'); // -// // TODO: Shouldn't be here, this should either be implemented on Ray if it's general enough, of just remain here as an artifact -// protected ___domain = (ray: Ray) => ray.map(_ => { -// const vertex: VData = _.cast(); -// return [vertex.vtype, vertex.size]; -// }); -// // /** // * Return the domain of the graph. // * // * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. // */ // // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. -// get domain(): Ray { return this.___domain(this.inputs) }; +// get domain(): Ray { return this.inputs.cast().domain; }; // // /** // * Return the domain of the graph. // * // * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. // */ -// get codomain(): Ray { return this.___domain(this.outputs) }; +// get codomain(): Ray { return this.outputs.cast().domain; }; // // vertex_data = (v = int): VData => this.vertices().at(v).cast(); // edge_data = (e = int): EData => this.edges().at(e).cast(); diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 47c92b9..cfefe77 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -1,12 +1,13 @@ import React, {useRef, useState} from "react"; import IEventListener from "../../js/react/IEventListener"; import {VisualizationCanvas} from "../../explorer/Visualization"; -import {add, AutoRay, AutoVertex, InterfaceOptions} from "../../explorer/OrbitMinesExplorer"; +import {_Continuation, add, AutoVertex, InterfaceOptions, SimpleRenderedRay} from "../../explorer/OrbitMinesExplorer"; import {Center} from "@react-three/drei"; import {useHotkeys} from "../../js/react/hooks/useHotkeys"; -import {Ray} from "../../explorer/Ray"; +import {DebugRay, DebugResult, Ray, RayType} from "../../explorer/Ray"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; -import {keys} from "lodash"; +import _ from "lodash"; +import {Children} from "../../../lib/typescript/React"; // TODO: Put the graphs setc at the top, invis lines, then draw them on hover, and maybe make surrounding stuff less visiable. // TODO: make some function which uses a custom input like position of the interface as the thing which breaks equivalences - ignorances. Basically a custom "equivalency function" @@ -41,10 +42,12 @@ const Interface = () => { combo: "arrowright", global: true, label: "", onKeyDown: () => { const { selection, rays } = Chyp.any; - const next = Ray.js("A").as_reference().o({ + const next = Ray.vertex().as_reference().o({ position: add(selection.any.position ?? [0, 0, 0], [i * 2, 0, 0]), scale }); + selection.continues_with(next); + // const next2 = Ray.js("A").as_reference().o({ // position: add(selection.any.position ?? [0, 0, 0], [i * 2, -30, 0]), // scale @@ -53,9 +56,6 @@ const Interface = () => { Chyp.any.selection = next; Chyp.any.rays = [...rays, next] - // selection.continues_with( - - // ); } }, { @@ -124,6 +124,109 @@ const Interface = () => { return ; } + const render = () => { + + } + + const DEBUG = true; + + const debug: DebugResult = {}; + selection.debug(debug); + + if (DEBUG) { + _.values(debug).forEach(ray => { + + }); + + return <> +
+ {_.values(debug).map(((_ray, index) => { + const scale = 1.5; + + const options = (ray: DebugRay, expected: InterfaceOptions): DebugRay & Required => { + const color = { + [RayType.VERTEX]: 'orange', + [RayType.TERMINAL]: '#FF5555', + [RayType.INITIAL]: '#5555FF', + [RayType.REFERENCE]: '#555555', + }[ray.type]; + + console.log('-') + console.log('expected', expected) + console.log('ray', ray) + return { + position: [0, 0, 0], + rotation: [0, 0, 0], + color, + scale, + + ...ray, // If set elsewhere, prefer that one instead + ...expected, // Expected based on current perspective + } + } + + const expected = (ref: string): InterfaceOptions => ref === 'None' ? {} : _.pick(debug[ref] as InterfaceOptions, 'position', 'rotation', 'color', 'scale'); + const interface_options = (ray: InterfaceOptions): InterfaceOptions => _.pick(ray, 'position', 'rotation', 'color', 'scale'); + + let ray = debug[_ray.label] = options(debug[_ray.label], { + position: [100, index * 20, 0], + // ...expected(debug[_ray.label].vertex) + }); + let vertex: InterfaceOptions = ray.vertex !== 'None' ? (debug[ray.vertex] = options(debug[ray.vertex], { + position: [100, index * 20, 0], + // ...expected(ray.label) + })) : {}; + let initial: InterfaceOptions = ray.initial !== 'None' ? (debug[ray.initial] = options(debug[ray.initial], { + position: add(ray.position, [-20 * scale, 0, 0]), + // ...expected(ray.label) + })) : {}; + let terminal: InterfaceOptions = ray.terminal !== 'None' ? (debug[ray.terminal] = options(debug[ray.terminal], { + position: add(ray.position, [20 * scale, 0, 0]), + // ...expected(ray.label) + })) : {}; + + const Group = ({ children }: Children) => { /// position={_default.position} rotation={vertex.rotation}> + return + {children} + + } + + const None = (options: InterfaceOptions) => (<_Continuation {...options} color="#AA0000" scale={1} />) + + const Extreme = ({type}: { type: RayType.INITIAL | RayType.TERMINAL }) => { + const options = interface_options(type === RayType.INITIAL ? initial : terminal); + + switch (ray.type) { + case RayType.REFERENCE: + case RayType.VERTEX: { + const vertex_options = interface_options(vertex); + + const a = type === RayType.INITIAL ? { terminal: vertex_options } : { initial: vertex_options }; + return ; + } + case type: { + return ; + } + case (type === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL): { + return <> + } + } + } + + return + + + + + }))} +
+ + } return <>
From df83100708457473f8d329da28a48591644bb120 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 23:12:36 +0100 Subject: [PATCH 033/138] 2024/02/09 - Reverse some debug options --- src/@orbitmines/explorer/Ray.spec.ts | 20 ++-- src/@orbitmines/external/chyp/ChypCanvas.tsx | 97 +++++++++----------- 2 files changed, 51 insertions(+), 66 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 8e3db38..000df04 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -17,16 +17,16 @@ describe("JS", () => { }) }); describe("Ray", () => { - test(".vertex.#.debug", () => { - const a = Ray.vertex().as_reference(); - const b = Ray.vertex().as_reference(); - a.continues_with(b); - - const debug = {}; - a.debug(debug); - - expect(debug).toEqual('') - }) +// test(".vertex.#.debug", () => { +// const a = Ray.vertex().as_reference(); +// const b = Ray.vertex().as_reference(); +// a.continues_with(b); +// +// const debug = {}; +// a.debug(debug); +// +// expect(debug).toEqual('') +// }) test(".o", () => { const ray = Ray.vertex().o({ a: 'b', diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index cfefe77..13004f8 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -4,7 +4,7 @@ import {VisualizationCanvas} from "../../explorer/Visualization"; import {_Continuation, add, AutoVertex, InterfaceOptions, SimpleRenderedRay} from "../../explorer/OrbitMinesExplorer"; import {Center} from "@react-three/drei"; import {useHotkeys} from "../../js/react/hooks/useHotkeys"; -import {DebugRay, DebugResult, Ray, RayType} from "../../explorer/Ray"; +import {DebugResult, Ray, RayType} from "../../explorer/Ray"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import _ from "lodash"; import {Children} from "../../../lib/typescript/React"; @@ -134,59 +134,51 @@ const Interface = () => { selection.debug(debug); if (DEBUG) { - _.values(debug).forEach(ray => { - - }); + // _.groupBy(_.values(debug), ray => ray.vertex); return <>
{_.values(debug).map(((_ray, index) => { - const scale = 1.5; - - const options = (ray: DebugRay, expected: InterfaceOptions): DebugRay & Required => { - const color = { - [RayType.VERTEX]: 'orange', - [RayType.TERMINAL]: '#FF5555', - [RayType.INITIAL]: '#5555FF', - [RayType.REFERENCE]: '#555555', - }[ray.type]; - - console.log('-') - console.log('expected', expected) - console.log('ray', ray) - return { - position: [0, 0, 0], - rotation: [0, 0, 0], + let ray = { + ...debug[_ray.label] + } + + const color = { + [RayType.VERTEX]: 'orange', + [RayType.TERMINAL]: '#FF5555', + [RayType.INITIAL]: '#5555FF', + [RayType.REFERENCE]: '#555555', + }[ray.type]; + + ray = { + ...ray, + ...({ color, - scale, + scale: 1.5, + position: [0, index * 20, 0] + } as InterfaceOptions) + } - ...ray, // If set elsewhere, prefer that one instead - ...expected, // Expected based on current perspective - } + debug[_ray.label] = ray; + + const _default: Required = { + position: [0, 0, 0], + rotation: [0, 0, 0], + scale: 1, + color: 'orange', + ..._.pick(ray, 'position', 'rotation', 'scale', 'color'), } - const expected = (ref: string): InterfaceOptions => ref === 'None' ? {} : _.pick(debug[ref] as InterfaceOptions, 'position', 'rotation', 'color', 'scale'); - const interface_options = (ray: InterfaceOptions): InterfaceOptions => _.pick(ray, 'position', 'rotation', 'color', 'scale'); + console.log(ray.label, [ray.initial, ray.vertex, ray.terminal].toString()) - let ray = debug[_ray.label] = options(debug[_ray.label], { - position: [100, index * 20, 0], - // ...expected(debug[_ray.label].vertex) - }); - let vertex: InterfaceOptions = ray.vertex !== 'None' ? (debug[ray.vertex] = options(debug[ray.vertex], { - position: [100, index * 20, 0], - // ...expected(ray.label) - })) : {}; - let initial: InterfaceOptions = ray.initial !== 'None' ? (debug[ray.initial] = options(debug[ray.initial], { - position: add(ray.position, [-20 * scale, 0, 0]), - // ...expected(ray.label) - })) : {}; - let terminal: InterfaceOptions = ray.terminal !== 'None' ? (debug[ray.terminal] = options(debug[ray.terminal], { - position: add(ray.position, [20 * scale, 0, 0]), - // ...expected(ray.label) - })) : {}; - - const Group = ({ children }: Children) => { /// position={_default.position} rotation={vertex.rotation}> - return + const initial: Required = { ..._default, position: [-20 * _default.scale, 0, 0] }; + + // Vertex as the origin for rotation + const vertex: Required = { ..._default, position: [0, 0, 0] } //, ...ray.vertex }; + const terminal: Required = { ..._default, position: [20 * _default.scale, 0, 0] }; + + const Group = ({ children }: Children) => { + return {children} } @@ -194,15 +186,13 @@ const Interface = () => { const None = (options: InterfaceOptions) => (<_Continuation {...options} color="#AA0000" scale={1} />) const Extreme = ({type}: { type: RayType.INITIAL | RayType.TERMINAL }) => { - const options = interface_options(type === RayType.INITIAL ? initial : terminal); + const options = type === RayType.INITIAL ? initial : terminal; switch (ray.type) { case RayType.REFERENCE: case RayType.VERTEX: { - const vertex_options = interface_options(vertex); - - const a = type === RayType.INITIAL ? { terminal: vertex_options } : { initial: vertex_options }; - return ; + const a = type === RayType.INITIAL ? { terminal: vertex } : { initial: vertex }; + return ; } case type: { return ; @@ -215,12 +205,7 @@ const Interface = () => { return - + }))} From 213313f3a9686a7ab4c68d595fdc28de9ef69ef7 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 23:53:22 +0100 Subject: [PATCH 034/138] 2024/02/09 - Start in debugging --- src/@orbitmines/external/chyp/ChypCanvas.tsx | 46 ++++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 13004f8..d3731f4 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -4,7 +4,7 @@ import {VisualizationCanvas} from "../../explorer/Visualization"; import {_Continuation, add, AutoVertex, InterfaceOptions, SimpleRenderedRay} from "../../explorer/OrbitMinesExplorer"; import {Center} from "@react-three/drei"; import {useHotkeys} from "../../js/react/hooks/useHotkeys"; -import {DebugResult, Ray, RayType} from "../../explorer/Ray"; +import {DebugRay, DebugResult, Ray, RayType} from "../../explorer/Ray"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import _ from "lodash"; import {Children} from "../../../lib/typescript/React"; @@ -23,7 +23,7 @@ const Interface = () => { const cursor: InterfaceOptions = { scale, rotation: [0, 0, Math.PI / 6 ], - color: '#FF5555' + color: '#555555' }; // TODO: Direct call to rerender on change, now there's lag @@ -133,11 +133,25 @@ const Interface = () => { const debug: DebugResult = {}; selection.debug(debug); - if (DEBUG) { - // _.groupBy(_.values(debug), ray => ray.vertex); + const Debug = () => { + const groups: string[][] = []; + _.values(debug).forEach(ray => { + for (let group of groups) { + if (group.includes(ray.label) || group.includes(ray.vertex)) { + group.push(...[ray.label, ray.vertex].filter(l => l !== 'None')); + return; + } + } + + groups.push([ray.label, ray.vertex].filter(l => l !== 'None')); + }); + + const group = (l: string): string[] => groups.find(group => group.includes(l))!; + const group_index = (l: string): number => groups.indexOf(group(l)); + const index_in_group = (l: string): number => group(l).indexOf(l); return <> -
+ {/*
*/} {_.values(debug).map(((_ray, index) => { let ray = { ...debug[_ray.label] @@ -150,12 +164,21 @@ const Interface = () => { [RayType.REFERENCE]: '#555555', }[ray.type]; + const group_x = _.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position)).map(position => position[0])[0]; + console.log(_.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position))) + ray = { ...ray, ...({ color, scale: 1.5, - position: [0, index * 20, 0] + // rotation: ray.type == RayType.REFERENCE ? [0, 0, Math.PI / 6] : [0, 0, 0], + position: [ + group_x ?? group_index(ray.label) * 20 * 1.5, + // (index_in_group(ray.label) + group_index(ray.label) + (group_x ? 0: 1)) * 30 * 1.5, + index * 20 * 1.5, + 0 + ] } as InterfaceOptions) } @@ -169,7 +192,7 @@ const Interface = () => { ..._.pick(ray, 'position', 'rotation', 'scale', 'color'), } - console.log(ray.label, [ray.initial, ray.vertex, ray.terminal].toString()) + // console.log(ray.label, [ray.initial, ray.vertex, ray.terminal].toString()) const initial: Required = { ..._default, position: [-20 * _default.scale, 0, 0] }; @@ -209,7 +232,11 @@ const Interface = () => { }))} -
+ + {groups.map(group => <> + {group.map(l => )} + )} + {/*
*/} } @@ -228,6 +255,9 @@ const Interface = () => { {rays.map((ray: Ray) => )} + + + {/**/}
From f25f77ebb197e22f4b2bedd75e3ccbc17bba5c32 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 9 Jan 2024 23:55:10 +0100 Subject: [PATCH 035/138] 2024/02/09 - Start in debugging --- src/@orbitmines/external/chyp/ChypCanvas.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index d3731f4..4db3444 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -165,7 +165,7 @@ const Interface = () => { }[ray.type]; const group_x = _.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position)).map(position => position[0])[0]; - console.log(_.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position))) + // console.log(_.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position))) ray = { ...ray, From f6b2687334c2da60625a6d43f410eee52380e108 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 13:09:35 +0100 Subject: [PATCH 036/138] 2024/02/10 - Removing some redundant stuff, some naive translations --- .../explorer/OrbitMinesExplorer.tsx | 366 +-- src/@orbitmines/explorer/Ray.ts | 74 +- src/@orbitmines/external/chyp/Chyp.ts | 2746 +++++++++-------- src/@orbitmines/external/chyp/ChypCanvas.tsx | 3 + 4 files changed, 1441 insertions(+), 1748 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index 1a19153..4b55748 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -1,17 +1,10 @@ -import React, {useEffect, useRef, useState} from 'react'; -import {AbstractDirectionality, Ray, RayType} from "./Ray"; +import React from 'react'; +import {Ray, RayType} from "./Ray"; import {VisualizationCanvas} from "./Visualization"; import {CatmullRomLine, Circle, CubicBezierLine, QuadraticBezierLine, Torus} from "@react-three/drei"; -import {useFrame, useThree,} from "@react-three/fiber"; -import {useDrag} from "@use-gesture/react"; -import {useSpring} from '@react-spring/three' -import {useHotkeys} from "../js/react/hooks/useHotkeys"; -import {WebGLRenderTarget} from "three"; import _ from "lodash"; -import IEventListener, {mergeListeners} from "../js/react/IEventListener"; -import {toPng} from "html-to-image"; +import IEventListener from "../js/react/IEventListener"; import {Children} from "../../lib/typescript/React"; -import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import {NotImplementedError} from "./errors/errors"; export const add = (a: number[], b: number[]): [number, number, number] => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; @@ -706,336 +699,8 @@ export const RenderedRay = ( return render; } -const InterfaceObject = ({ - scale = 1, - ...props -}: any) => { - const ref = useRef(); - const [selection, setSelection] = useState( - Ray.vertex().as_reference() - ); - const [controls, setControls] = useState( - Ray.vertex().as_reference() - ); - - const { - gl: renderer, - camera, - scene, - raycaster - } = useThree(); - - // One could abstractly realize hotkeys, or any kind of control system as a possible temporal directionality. - const hotkeys = useHotkeys(); - hotkeys.set( - { - combo: "shift + d", global: true, label: "", onKeyDown: () => { - // const link = document.createElement('a') - // link.setAttribute('download', `canvas.png`) - // link.setAttribute('href', renderer.domElement.toDataURL('image/png').replace('image/png', 'image/octet-stream')) - // link.click() - - // const box = new Box3().setFromObject(ref.current); - // const size = box.getSize(new Vector3()); - // - // const width = Math.ceil(size.x); - // const height = Math.ceil(size.y); - // const width = 500; - // const height = 500; - // - // const renderTarget = new WebGLRenderTarget(renderer.domElement.width, renderer.domElement.height); - // - // renderer.setRenderTarget(renderTarget); - // renderer.render(scene, camera); - // renderer.setRenderTarget(null); - // - // const canvasX = (0 + 1) / 2 * renderTarget.width; - // const canvasY = (-0 + 1) / 2 * renderTarget.height; - // // const canvasX = Math.ceil(box.min.x + 1) - Math.ceil(renderTarget.width / 2); - // // const canvasY = Math.ceil(-box.min.y + 1) - Math.ceil(renderTarget.height / 2); - // - // const pixels = new Uint8Array(width * height * 4); - // renderer.readRenderTargetPixels(renderTarget, canvasX, canvasY, width, height, pixels); - // - // const imageData = new ImageData(new Uint8ClampedArray(pixels), width, height); - // - // const image = document.createElement('canvas'); - // image.width = width; - // image.height = height; - // image.getContext('2d')!.putImageData(imageData, 0, 0); - // - // const link = document.createElement('a') - // link.download = 'test.png'; - // link.href = image.toDataURL('test.png'); - // link.click(); - - - toPng(renderer.domElement, { - cacheBust: true, - backgroundColor: '#1C2127' - }) - .then((dataUrl) => { - const link = document.createElement('a') - link.download = `${new Date().toISOString()}.png` - link.href = dataUrl - link.click() - }) - .catch((err) => { - console.log(err) - }); - } - }, { - combo: "arrowright", global: true, label: "", onKeyDown: () => { - const next = selection.continues_with( - Ray.vertex().as_reference() - ); - - setSelection(next) - } - } - ); - - const addHotkey = (hotkey: HotkeyConfig) => { - - } - - useEffect(() => { - console.log(selection.to_wolfram_language()) - }, [selection]); - - useEffect(() => { - - // const debug = {}; - // A.as_reference() - // .continues_with(new Ray({ js: () => Option.Some("B") }).as_reference()) - // .continues_with(new Ray({ js: () => Option.Some("C") }).as_reference()) - // .debug(debug) - - // console.log(debug) - - // console.log( - // new Ray({ js: () => Option.Some('empty')}) - // .as_reference() - // .continues_with(new Ray({ js: () => Option.Some("A") }).as_reference()) - // // .continues_with(new Ray({ js: () => Option.Some("B") }).as_reference()) - // // .continues_with(new Ray({ js: () => Option.Some("C") }).as_reference()) - // .to_wolfram_language() - // ) - // - // const A = new Ray({ js: () => Option.Some('empty')}) - // .as_reference() - // .continues_with(new Ray({ js: () => Option.Some("A") }).as_reference()); - // - // A - // .continues_with(new Ray({ js: () => Option.Some("B") }).as_reference()) - // .continues_with(new Ray({ js: () => Option.Some("C") }).as_reference()) - - // console.log( - // A.to_wolfram_language() - // ) - // console.log( - // new Ray({ js: () => Option.Some('empty')}) - // .as_reference() - // .continues_with(new Ray({ js: () => Option.Some("A") }).as_reference()) - // .continues_with(new Ray({ js: () => Option.Some("B") }).as_reference()) - // .continues_with(new Ray({ js: () => Option.Some("C") }).as_reference()) - // .to_wolfram_language() - // ) - - // console.log( - // A.as_reference().to_wolfram_language() - // ) - }, []) - - // hotkeys.set( - // { combo: "arrowright", global: true, label: "Refresh data", onKeyDown: () => { - // selected.next().match({ - // Some: (ray) => setSelected(ray), - // None: () => console.log('no more') - // }) - // }}, { combo: "arrowleft", global: true, label: "Refresh data", onKeyDown: () => { - // selected.previous().match({ - // Some: (ray) => setSelected(ray), - // None: () => console.log('no more') - // }) - // }}); - - const [{ x, y }, api] = useSpring(() => ({ x: 0, y: 0 })) - - const [position, setPosition] = useState([0, 0, 0]); - const [movement, setMovement] = useState([0, 0, 0]); - - const drag = useDrag(({ down, movement: [mx, my] }) => { - api.start({ x: down ? mx : 0, y: down ? my : 0, immediate: down }); - - document.body.style.cursor = down ? 'grabbing' : 'auto'; - - if (down) { - setMovement([x.get(), -y.get(), 0]); - } else { - setPosition([position[0] + x.get(), position[1] - y.get(), 0]); - setMovement([0, 0, 0]) - } - }); - - useFrame(() => { - const renderTarget = new WebGLRenderTarget(renderer.domElement.width, renderer.domElement.height); - - // From a position, retrieve a directionality which defines what is at that position. - // const position = (position: Vector3): Extreme> => { - // // const ray = new Raycaster(new THREEVector3(0, 0, 0), new THREEVector3(0, 0, 1)) - // // const intersections = ray.intersectObjects(scene.children, true); - // // console.log(intersections.length) - // // intersections.forEach(intersection => console.log(intersection.object.id)) - - // renderer.setRenderTarget(renderTarget); - // renderer.render(scene, camera) - // renderer.setRenderTarget(null) - // - // const canvasX = (0 + 1) / 2 * renderTarget.width; - // const canvasY = (-0 + 1) / 2 * renderTarget.height; - // - // const pixelBuffer = new Uint8Array(4); - // renderer.readRenderTargetPixels(renderTarget, canvasX, canvasY, 1, 1, pixelBuffer); - // - // // Access pixel values - // const red = pixelBuffer[0]; - // const green = pixelBuffer[1]; - // const blue = pixelBuffer[2]; - // const alpha = pixelBuffer[3]; - // - // const pos = position([0, 0, 0]); - }); - - const currentPosition = add(position, movement); - - return ( - - - {/**/} - {/* */} - {/* Rewriting a Binary Superposition to a specific value*/} - - {/* */} - {/**/} - - ) -} - -class InterfaceObjec { - - - // position = (): Vector3 => {} - // - // pixels = (): Vector3 => {} - - /** - * As long as the setup cannot itself render objects and have access to that level of the stack, it will merely be an inaccessible translation layer between the two. - */ - render = () => { - // Translates to ThreeJS ( - } - - /** - * - ThreeJS layer - * - 3D layer - * - camera position - * - * Generalize these - * - Any layer - * - Any "camera"/observer, different rays. - */ - - -} - -const Test2 = ({ ray, position }: { ray: Ray, position: [number, number, number] }) => { - const circle = { - radius: 3, - color: "orange", - segments: 30 - } - const torus = { - // Radius of the torus, from the center of the torus to the center of the tube. Default is 1. - radius: 3, - color: "orange", - tube: { - width: 1, - segments: 200 - }, - segments: 200, - } - - if (ray.is_terminal() || ray.is_initial()) { - return ( - - - {[...ray.traverse()].map((vertex, i) => ( - - ))} - - ) - } - - return ( - - ) -} - - -// useEffect(() => { -// for (let vertex of ray.traverse()) { -// /** -// * In this case should be a reference and thus -// * [--|--] -// * -// * So in the case of [0, 1], this would be a reference to the Iterator, in the case of 1/2/3/4/5, a reference to their respective values. -// */ -// const reference = vertex.vertex; -// -// if (reference.is_some()) { -// if (reference.vertex.is_none()) -// continue; -// -// // This would be the Iterator, or the numbers respectively. -// const dereferenced = reference.vertex; -// /** -// * Can again be any of these: -// * [--|--] -// * [--| ] -// * [ |--] -// * -// */ -// -// console.log('type:', reference.type); -// console.log('structure at', dereferenced.js()) -// -// console.log(' traversing nested reference'); -// for (let nested of reference.traverse()) { -// const nested_reference = nested.vertex; -// -// if (nested_reference.is_some()) { -// if (nested_reference.vertex.is_none()) -// continue; -// -// const nested_dereferenced = nested_reference.vertex; -// -// console.log('type:', nested_reference.toString()); -// console.log('structure at', nested_dereferenced.js()) -// } -// } -// console.log(' done'); -// } -// } -// }, []) const OrbitMinesExplorer = ( { @@ -1044,37 +709,12 @@ const OrbitMinesExplorer = ( listeners?: IEventListener[], } ) => { - // const ray = JS.Iterable([14, 15, [[6, 7, 8, 9, 10, 11], 100], 1, 2, 3, 4, 5, 16, false]).as_ray(); - // console.log(ray.to_wolfram_language()) - - // visualization_config - // hotkey/interface_config - - const listener: IEventListener = { - - } return ( - - - - {/**/} - {/* */} - - {/* */} - {/* */} - {/* */} - {/* */} - {/**/} - {/**/} - {/* */} - {/**/} ); }; diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 7ab6c9f..4890db0 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -206,6 +206,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } } + /** + * next = (): Option => JS.Iterable(this.traverse({ steps: 1 })).as_ray(); + * previous = (): Option => JS.Iterable(this.traverse({ steps: 1, direction: { reverse: true } })).as_ray(); + */ + // TODO: These necessarily rever to something which allows you to ask the question of 'next' again. It could return many values (initial/terminal?), a single one: vertex; on which again more structure like a list or something could be defined... + get previous(): Ray { throw new NotImplementedError(); } + get next(): Ray { throw new NotImplementedError(); } // TODO: Could need equivalence/skip logic, "already was here", or say, necessarily, it should get visited again, ... again this thing is hard to say generally. + // TODO: This is the same with rewrite/compile/compose/dpo ... + // TODO NEEDS TO CHECK IF THERE'S SOME INITIAL DEFIEND ; for defining if it has halted protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother @@ -367,75 +376,16 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return obj; } - to_wolfram_language = (): string => { - const hyperEdges: string[][] = []; - const options: any = {}; - - const debug = {}; - this.debug(debug); - - const vertexStyle = (ray: any): string => { - switch (ray.type) { - case RayType.INITIAL:{ - return 'Darker@Red' - } - case RayType.TERMINAL: { - return 'Lighter@Red' - } - case RayType.REFERENCE: { - if (ray.vertex === 'None') // empty reference - return 'Lighter@Orange'; - - return 'Orange' - } - case RayType.VERTEX: { - return 'Lighter@Blue' - } - default: { - throw '??' - } - } - } - - _.valuesIn(debug).forEach((ray: any) => { - console.log(ray) - - if (ray.initial !== 'None' && ray.terminal !== 'None') { - const edge: string[] = [ray.initial, ray.label, ray.terminal].filter(vertex => vertex !== 'None'); - hyperEdges.push(edge); - } - - if (ray.vertex !== 'None') { - hyperEdges.push([ray.label, ray.vertex]); - - (options['EdgeStyle'] ??= {})[`{${[ray.label, ray.vertex].join(',')}}`] = 'Orange' - } - - (options['VertexStyle'] ??= {})[ray.label] = vertexStyle(ray); - }) - - return `ResourceFunction["WolframModelPlot"][{${hyperEdges - .filter(hyperEdge => hyperEdge.length !== 0) - .map(hyperEdge => - `{${hyperEdge.join(',')}}` - ).join(',')}},VertexLabels->All,${ - _.map(options, (mapping, option) => - `${option} -> <|${ - _.map(mapping, (value, key) => `${key} -> ${value}`) - .join(',')}|>`) - .join(',')}]`; - } /** * TODO: This should be constructed at the vertex and in general unsolvable */ static _label: number = 0; - __label: string | undefined; get label(): string { - if (this.__label !== undefined) - return this.__label; + if (this.any.label !== undefined) + return this.any.label; - return this.__label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; + return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; } // length: number; diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index 07f147d..a516426 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1,1323 +1,1423 @@ -// import {JS, Ray} from "../../explorer/Ray"; -// import {NotImplementedError} from "../../explorer/errors/errors"; -// -// /** -// * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. -// * GitHub: https://github.com/akissinger/chyp -// * -// * A simple way of phrasing this conversion, is that the concept of a 'Vertex', 'Edge', 'Graph', 'Rule', ..., 'Rewrite' are merged into one thing: a Ray. -// * -// * NOTE: -// * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. -// * -// * - The .copy()'s are implemented on Ray. -// * -// * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. -// * -// * TODO: Probably want all these types at runtime, to display them -// * -// * TODO: Graph boundary is automatic with this structure? -// * -// * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? -// * -// * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. -// * -// * TODO: Can just move the terminal which holds the oointer to the boundary -// * -// * TODO: Automatically generate visual examples of all the methods -// * -// * TODO: Runtime errors as rays -// * -// * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph -// */ -// /** -// * TODO: These coordinates used for inferences? -// * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" -// */ -// -// export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// -// export const Color = (t1: Ray = str('')): Ray => { throw new NotImplementedError() }; -// -// export class ValueError extends Error {} -// -// /** -// * Non-default vertex types are identified by a string label -// * -// * str() | None() - No overloading in TypeScript ;( -// */ -// export const VType = JS.Iterable([str, None]); -// -// /** -// * An error occurred in the graph backend. -// * -// * TODO probably hooked as a boolean, one successful the other not -// */ -// export class GraphError extends Error {} -// export class RuleError extends Error {} -// -// /** -// * Used for debugging (the matcher) -// */ -// const DEBUG = true; // TODO; Generalize -// const log = (s: string) => { -// if (!DEBUG) -// return; -// -// console.log(s); -// } -// -// /** -// * Data associated with a single vertex. -// */ -// export class VData extends Ray { -// // The vertex type. -// vtype = this.property('vtype', None); -// -// // The register size (number of bundled parallel wires) of the vertex. -// size = this.count; // Implemented on Ray.count -// -// // TODO: These infers will probably be removed? -// // Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). -// infer_type = this.property('infer_type', bool(False)) -// // Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). -// infer_size = this.property('infer_size', bool(False)) -// -// // x-coordinate at which to draw the vertex. -// x = this.property('y', int(0)) -// // y-coordinate at which to draw the vertex. -// y = this.property('y', int(0)) -// -// highlight = this.property('highlight', bool(False)) -// value = this.property('value') -// -// /** -// * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. -// * -// * TODO ; // set[int] = set() -// * TODO ; these are just the initial/terminal sides of a Ray. they're just duplicated -// */ -// get in_edges(): Ray { throw new NotImplementedError(); } -// get out_edges(): Ray { throw new NotImplementedError(); } -// -// /** -// * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. -// */ -// get in_indices(): Ray { return this.initial } // -// get out_indices(): Ray { throw new NotImplementedError(); } -// -// is_input = (): Ray => this.in_indices.count.as_int() > 0; -// is_output = (): Ray => this.out_indices.count.as_int() > 0; -// is_boundary = (): Ray => this.is_input() || this.is_output(); -// -// // TODO: Probably generalizable -// -// /** -// * -// * @param other -// */ -// merge = (other: VData): Ray => { -// // TODO: other is destroyed -// // TODO: Vertices -// // this.initial.equivalent(other.initial); -// // this.terminal.equivalent(other.initial); -// -// /* -// -// vd = self.vertex_data(v) -// # print("merging %s <- %s" % (v, w)) -// -// # Where vertex `w` occurs as an edge target, replace it with `v` -// for e in self.in_edges(w): -// ed = self.edge_data(e) -// ed.t = [v if x == w else x for x in ed.t] -// vd.in_edges.add(e) -// -// # Where vertex `w` occurs as an edge source, replace it with `v` -// for e in self.out_edges(w): -// ed = self.edge_data(e) -// ed.s = [v if x == w else x for x in ed.s] -// vd.out_edges.add(e) -// -// # Wherever `w` occurs on the graph boundary, replace it with `v` -// self.set_inputs([v if x == w else x for x in self.inputs]) -// self.set_outputs([v if x == w else x for x in self.outputs]) -// -// # Remove references to `w` from the graph -// self.remove_vertex(w) -// -// */ -// -// throw new NotImplementedError(); -// } -// -// fresh = (): VData => { -// // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. -// -// // vtype=vd.vtype, size=vd.size, -// // x=vd.x, y=vd.y, value=vd.value -// -// } -// -// // TODO: Shouldn't be here, this should be implemented on Ray if it's general enough -// get domain(): Ray { return JS.Iterable([this.vtype, this.size]) }; -// -// } -// -// /** -// * Data associated with a single edge. -// */ -// export class EData extends Ray { -// -// get source() { return this.s }; -// get target() { return this.t }; -// -// // TODO: this is just the initial frame -// get s(): Ray { throw new NotImplementedError(); } -// // TODO: this is just the terminal frame -// get t(): Ray { throw new NotImplementedError(); } -// -// fg = this.property('bg', Color()); -// bg = this.property('bg', Color()); -// x = this.property('y', int(0)); -// // y-coordinate at which to draw the vertex. -// y = this.property('y', int(0)); -// highlight = this.property('highlight', bool(False)) -// hyper = this.property('value', bool(True)) -// value = this.property('value') -// -// __repr__ = (): Ray => { throw new NotImplementedError(); -// // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' -// } -// -// // TODO: More stuff to relate it to the screen that shouldnt be here. -// /** -// * Return how many width 'units' this box needs to display nicely. -// * -// * This uses a simple rule: -// * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. -// * - Otherwise draw as a larger (size 2) box. -// */ -// box_size = (): Ray => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); -// -// domain = (): Ray => this.source.cast().domain; -// codomain = (): Ray => this.target.cast().domain; -// -// toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL -// } -// -// /** -// * A hypergraph with boundaries. -// * -// * This is the main data structure used by Chyp. It represents a directed -// * hypergraph (which we call simply a "graph") as two dictionaries for -// * vertices and (hyper)edges, respectively. Each vertex is associated with a -// * `VData` object and edge edge with an `EData` object, which stores -// * information about adjacency, position, label, etc. -// * -// * The particular flavor of hypergraphs we use associate to each hyperedge a -// * list of source vertices and a list of target vertices. The hypergraph -// * itself also has a list of input vertices and a list of output vertices, -// * which are used for sequential composition and rewriting. -// */ -// export class Graph extends Ray { -// -// get vindex(): Ray { return this.vdata.index.max(0); } -// get eindex(): Ray { return this.edata.index.max(0); } -// -// // Mapping from integer identifiers of each vertex to its data. -// vdata = this.property('vertices'); -// // Mapping from integer identifiers of each hyperedge to its data. -// edata = this.property('edges'); -// -// // TODO .keys -// vertices = this.property('vertices'); -// edges = this.property('edges'); -// -// /** -// * Return the domain of the graph. -// * -// * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. -// */ -// // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. -// get domain(): Ray { return this.inputs.cast().domain; }; -// -// /** -// * Return the domain of the graph. -// * -// * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. -// */ -// get codomain(): Ray { return this.outputs.cast().domain; }; -// -// vertex_data = (v = int): VData => this.vertices().at(v).cast(); -// edge_data = (e = int): EData => this.edges().at(e).cast(); -// -// // TODO: Shouldnt be here -// ___next_index = (name = int(-1), index: Ray): Ray => { -// // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) -// const current = name === -1 ? index : Math.max(name, index); -// return current + 1; -// } -// -// /** -// * Add a new vertex to the graph. -// * -// * @param name The value carried by this vertex (currently unused). -// * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. -// * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). -// */ -// add_vertex = (name = int(-1), vertex: VData): VData => { -// this.vindex = this.___next_index(name, this.vindex); -// -// this.vdata[this.vindex - 1] = vertex; -// return vertex; -// } -// -// /** -// * Add a new hyperedge to the graph. -// * -// * @param s -// * @param t -// */ -// add_edge = (name = int(-1), edge: EData): EData => { -// this.eindex = this.___next_index(name, this.eindex); -// -// this.edata[this.eindex - 1] = edge; -// -// // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) -// // for v in s: -// // self.vdata[v].out_edges.add(e) -// // for v in t: -// // self.vdata[v].in_edges.add(e) -// -// return edge; -// } -// // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. -// -// /** -// * Remove a vertex from the graph. -// * -// * This removes a single vertex. -// * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. -// * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. -// * -// * @param v -// * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. -// */ -// remove_vertex = (v = int, strict: boolean = false): Ray => { -// // TODO: destroy any reference of it (could just do this lazy) -// // TODO: as delegation -// -// if (strict) { -// if (this.vertex_data(v).in_edges.count.as_int() > 0 || this.vertex_data(v).out_edges > 0) { -// throw new ValueError('Attempting to remove vertex with adjacent' -// + 'edges while strict == True.'); -// } -// -// if (this.inputs.includes(v) || this.outputs.includes(v)) { -// throw new ValueError('Attempting to remove boundary vertex while' -// + 'strict == True.'); -// -// }// TODO CAN BE SIMPLIFIED -// } -// -// // in/out edges from all vertices -// delete this.vdata[v]; -// } -// -// /** -// * Remove an edge from the graph. -// * -// * @param e Integer identifier of the edge to remove. -// */ -// remove_edge = (e = int): Ray => { -// // TODO: destroy any reference of it (could just do this lazy) -// // in/out edges from all vertices -// delete this.edata[e]; -// } -// -// // TODO: Can these be overlaoded in properties using -=, += in TS? -// -// /** -// * Append `inp` to the inputs of the graph. -// * -// * @param inp The list of vertex integer identifiers of the appended inputs. -// */ -// add_inputs = (inp = list(int)): Ray => { -// this.inputs.continues_with(inp); // TODO: Perhaps splat -// } -// /** -// * Append `outp` to the outputs of the graph. -// * -// * @param outp The list of vertex integer identifiers of the appended outputs. -// */ -// add_outputs = (outp = list(int)): Ray => { -// this.outputs.continues_with(outp); // TODO: Perhaps splat -// } -// // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) -// -// -// // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. -// -// // Return the list of vertex ids of the graph inputs. -// get inputs(): Ray { throw new NotImplementedError(); } -// // Return the list of vertex ids of the graph outputs. -// get outputs(): Ray { throw new NotImplementedError(); } -// -// // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs -// set inputs(ray = list(int)) { throw new NotImplementedError(); } -// set outputs(ray = list(int)) { throw new NotImplementedError(); } -// -// // TODO: Move these to a "reference-like" structure, need to be on VData.. -// -// /** -// * These are all just slightly differently abstracted in TypeScript here to make them a little more native. -// */ -// set_inputs = (inp = list(int)): Ray => this.inputs = inp; -// set_outputs = (outp = list(int)): Ray => this.outputs = outp; -// -// /** -// * All these are just delegations from some Vertex/Edge structure. -// */ -// // .vertices -// num_vertices = (): Ray => this.vertices().count.as_int(); -// -// // .edges -// num_edges = (): Ray => this.edges().count.as_int(); -// -// // .vertex_data -// is_input = (v = int): Ray => this.vertex_data(v).is_input(); -// is_output = (v = int): Ray => this.vertex_data(v).is_output(); -// is_boundary = (v = int): Ray => this.vertex_data(v).is_boundary(); -// in_edges = (v = int): Ray => this.vertex_data(v).in_edges; -// out_edges = (v = int): Ray => this.vertex_data(v).out_edges; -// -// // .edge_data -// source = (e = int): Ray => this.edge_data(e).source; -// target = (e = int): Ray => this.edge_data(e).target; -// edge_domain = (edge_id = int): Ray => this.edge_data(edge_id).domain(); -// edge_codomain = (edge_id = int): Ray => this.edge_data(edge_id).codomain(); -// -// /** -// * Return vertices that lie on a directed path from any of `vs`. -// * @param vs -// */ -// successors = (vs = Iterable(int)): Ray => { -// // TODO: Just traverse the rays, deduplicate using the index, where vs is one or more (so again which part of the ray is selected). -// -// -// throw new NotImplementedError(); -// } -// -// /** -// * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. -// * -// * @param v Integer identifier of the vertex into which to merge `w`. -// * @param w Integer identifier of the vertex to merge into `v`. -// */ -// merge_vertices = (v = int, w = int): Ray => this.vertex_data(v).merge(this.vertex_data(w)); -// -// /** -// * Split a vertex into copies for each input, output, and tentacle. -// * -// * This is used for computing pushout complements of rules that aren't left-linear. -// * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). -// * -// * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. -// * -// * @param v Integer identifier of vertex to be exploded. -// */ -// explode_vertex = (v = int): Ray => { -// const vertex = this.vertex_data(v); -// -// // TODO; This just seems like another copy which minor changes -// -// const next_inputs = empty(); -// const next_outputs = empty(); -// -// const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process -// vertex: VData, -// boundary: (vertex: VData) => Ray, -// next_boundary: Ray -// ) => { -// // TODO: It's just a duplicated process for vertex/edge since their definition is separataed -// -// // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. -// // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs]) -// // TODO: Basically a copy, and replace this one vertex -// -// // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. -// boundary(vertex).all(e => { -// const edge: EData = e.cast(); -// -// edge.t = edge.t -// .map(target => { -// if (target === v) -// return target; -// -// const fresh_vertex = vertex.fresh(); -// next_boundary.add(this.add_vertex(fresh_vertex)) -// boundary(fresh_vertex).add(edge); -// }) -// }); -// -// } -// -// // TODO: It's always just duplicated for both ends, -// __temp(vertex, (vertex) => vertex.in_edges, next_inputs); -// __temp(vertex, (vertex) => vertex.out_edges, next_outputs); -// -// // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. -// vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal -// vertex.out_edges.clear(); -// -// // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). -// this.remove_vertex(vertex, true); -// -// return [next_inputs, next_outputs]; -// } -// -// -// insert_id_after = (v = int): Ray => { throw new NotImplementedError(); } -// -// /** -// * Take the monoidal product of this graph in-place with another. -// * -// * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. -// * -// * @param other -// * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. -// */ -// tensor = (other: Graph, layout: boolean = true): Ray => { -// -// const a = this; -// const b = other; -// -// const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] -// -// tensor.initial.any.y -= -// tensor.initial.any.y.max(); // max_self -// -// tensor.terminal.any.y -= -// (layout ? tensor.terminal.any.y.min() : 0) + 1; // min_other TODO: Why + 1 ? -// -// /** -// * # self.set_inputs(self.inputs + [vmap[v] for v in other.inputs]) -// * # self.set_outputs(self.outputs + [vmap[v] for v in other.outputs]) -// * -// * # Add the inputs and outputs of the other graph to this one. -// * self.add_inputs([vmap[v] for v in other.inputs]) -// * self.add_outputs([vmap[v] for v in other.outputs]) -// */ -// // TODO: Add equivalence/reference on the inputs/output extremes. -// } -// -// /** -// * Sequentially compose this graph in-place with another. -// * -// * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. -// */ -// compose = (other: Graph): Ray => { -// // TODO Just matching outputs and inputs.. -// -// const a = this; -// const b = other; -// -// // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" -// const compose: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] -// -// // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. -// -// // TODO: This is just again an equivalence type check on the ends of the ray -// -// // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs -// -// { -// if (compose.initial.count.as_int() !== compose.terminal.count.as_int()) -// throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed -// -// /** -// * for output_id, input_id in zip(self_outputs, other_inputs): -// * output_data = self.vertex_data(output_id) -// * input_data = other.vertex_data(input_id) -// * if output_data.vtype != input_data.vtype: -// * if not (output_data.infer_type or input_data.infer_type): -// * raise GraphError( -// * f'Codomain {self.codomain()} does not ' -// * + f'match domain {other.domain()}' -// * ) -// * if output_data.size != input_data.size: -// * if not (output_data.infer_size or input_data.infer_size): -// * raise GraphError( -// * f'Codomain {self.codomain()} does not ' -// * + f'match domain {other.domain()}' -// * ) -// */ -// } -// -// /** -// * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. -// */ -// -// // Compute the max x-coordinate of the edges and vertices in this graph. -// -// // TODO: Again, recursively going through everything defined on the initial side (outputs) -// // Shift all vertices and edges of this graph below the x-axis. -// compose.initial.any.x -= -// compose.initial.any.x.max(); // max_self -// -// // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] -// compose.terminal.any.x -= -// compose.terminal.any.x.min(); // min_other -// -// // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. -// /** -// * plug1 = self.outputs -// * plug2 = [vmap[v] for v in other.inputs] -// * -// * if len(plug1) != len(plug2): -// * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' -// * + f'outputs into one with {len(plug2)} inputs') -// * -// * self.set_outputs([vmap[v] for v in other.outputs]) -// */ -// -// // [outputs to inputs] -// // Go through pairs of vertices from each plug -// compose.zip().all(([input, output]) => { -// /** -// * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. -// */ -// -// // TODO: does this ever happen??? -// // while p1 in quotient: -// // p1 = quotient[p1] -// // while p2 in quotient: -// // p2 = quotient[p2] -// -// -// // TODO, Again the same equivalence check for loops etc.. -// { -// // If the resulting p1 and p2 are not the same vertex, merge them. -// if (input === output) -// return; -// -// // TODO; DO this on the vertices; -// // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) -// -// // If both vertices have flexible types that are not equal, raise an error due to ambiguity. -// // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. -// -// -// // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. -// -// ['vtype', 'size'].forEach(structure => { -// const infer = `infer_${structure}`; -// -// if (input[infer] && output[infer] && input[structure] !== output[structure]) { -// throw GraphError(`Ambiguous vertex ${structure} during composition.`) -// -// } else if (input[infer]) { -// // Otherwise, if one vertex has a flexible type, ensure the vertex types match. -// // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it -// // TODO: Again both sides same thing.. -// input[structure] = output[structure]; // TODO: Generalized structure -// input[infer] = false; -// } else if (output.infer_type) { -// output[structure] = input[structure]; -// output[infer] = false; -// } -// }); -// -// input.merge(output); -// // # Register than p2 has been merged into p1. -// // quotient[p2] = p1 -// } -// }); -// } -// -// /** -// * Return the tensor product of this graph with another. -// * -// * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them -// */ -// __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); -// -// /** -// * Return the composition of the current graph with `other`. -// * -// * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. -// * @param other -// */ -// __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); -// -// /** -// * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer -// */ -// ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { -// const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. -// something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? -// return a_copy; // Could generalize to either end -// } -// -// /** -// * Set the `highlight` flag for a set of vertices and edges. -// * -// * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. -// * -// * @param vertices A set of vertices to highlight. -// * @param edges A set of edges to highlight. -// */ -// highlight = (vertices = set(int), edges = set(int)): Ray => { -// // TODO Again, these could be merged -// this.vdata -// .filter(vertex => vertices.includes(vertex)) -// .all(vertex => vertex.cast().highlight = bool(true)); -// this.edata -// .filter(edge => edges.includes(edge)) -// .all(edge => edge.cast().highlight = bool(true)); -// -// -// } -// -// /** -// * Clear the `highlight` flag for all vertices/edges. -// * -// * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. -// */ -// unhighlight = (): Ray => { -// // TODO: These could be merged -// this.vdata.highlight = false; -// this.edata.highlight = false; -// } -// } -// -// export class Chyp extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// -// /** -// * Load a .chyp graph file from the given path. -// */ -// load_graph = (path = str) => { -// // TODO: From localStorage for now? -// // with open(path) as f: -// // g = graph_from_json(f.read()) -// } -// -// /** -// * Return a graph corresponding to the identity map. -// * -// * This graph has a single vertex which is both an input and an output. -// */ -// identity = (vertex: VData): Graph => { -// const graph = new Graph(); -// -// vertex.x = 0; // TODO automatic>? -// vertex.y = 0; -// graph.add_vertex(int(-1), vertex); -// // TODO synce input/output automatically? -// // g.set_inputs([v]) -// // g.set_outputs([v]) -// -// return graph; -// } -// -// -// ___map_domain = (domain: Ray, _default: VData): Ray => { -// return domain.map(([vtype, size], i) => { -// const vertex: VData = _default.copy().cast(); -// // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere -// vertex.x = -1.5; -// vertex.y = i - (i-1) / 2; -// -// return vertex; -// }) -// } -// -// /** -// * Return a graph with one hyperedge and given domain and codomain. -// * -// * @param _default -// * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. -// * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. -// */ -// gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { -// const graph = new Graph(); -// -// const inputs = this.___map_domain(domain, _default) -// .map(vertex => graph.add_vertex(vertex)); -// const outputs = this.___map_domain(codomain, _default) -// .map(vertex => graph.add_vertex(vertex)); -// -// // TODO This is probably automatic at some point, remove -// const edge = new EData(); -// edge.s = inputs; -// edge.t = outputs; -// graph.add_edge(int(-1), edge); -// // g.set_inputs(inputs) -// // g.set_outputs(outputs) -// -// return graph; -// } -// -// /** -// * Return a graph corresponding to the given permutation. -// * -// * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. -// * -// * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. -// * -// * @param p A permutation given as an n-element list of integers from 0 to n-1. -// * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. -// */ -// perm = (p = list(int), domain: Ray, _default: VData) => { -// -// const graph = new Graph(); -// const num_wires = p.count.as_int(); -// -// if (num_wires !== domain.count.as_int()) -// throw new GraphError(`Domain ${domain} does not match length of permutation.`) -// -// // TODO use ___map_domain -// const inputs = domain.map(([vtype, size], i) => { -// const vertex: VData = _default.copy().cast(); -// // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere -// vertex.x = 0; -// vertex.y = i - (num_wires - 1) / 2; -// -// return vertex; -// }) -// .map(vertex => graph.add_vertex(vertex)); -// // const outputs = num_wires.range(i => [inputs[p[i]]) -// -// // TODO Should be automatic -// // g.set_inputs(inputs) -// // g.set_outputs(outputs) -// return graph; -// } -// -// graph_from_json = (json_string = str): Graph => { -// const json = JSON.parse(json_string().as_string()); // TODO -// -// const graph = new Graph(); -// -// // TODO: Don't do this so naively -// // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), -// // y=float(vd["y"] if "y" in vd else 0.0), -// // value=vd["value"] if "value" in vd else "", -// // name=int(v)) -// // for e, ed in j["edges"].items(): -// // g.add_edge(s=[int(v) for v in ed["s"]], -// // t=[int(v) for v in ed["t"]], -// // value=ed["value"] if "value" in ed else "", -// // x=float(ed["x"]) if "x" in ed else 0.0, -// // y=float(ed["y"]) if "y" in ed else 0.0, -// // hyper=bool(ed["hyper"]) if "hyper" in ed else True, -// // name=int(e)) -// // -// // g.set_inputs([int(v) for v in j["inputs"]]) -// // g.set_outputs([int(v) for v in j["outputs"]]) -// // json.vertices.forEach(((vertex, i) => graph.add_vertex( -// // i, -// // new VData() -// // )); -// -// return graph; -// } -// -// /** -// * # def wide_id() -> Graph: -// * # return gen("id", 1, 1) -// * -// * # def id_perm(p: List[int]) -> Graph: -// * # g = Graph() -// * # size = len(p) -// * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] -// * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] -// * -// * # for i in range(size): -// * # y = i - (size-1)/2 -// * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) -// * -// * # g.set_inputs(inputs) -// * # g.set_outputs(outputs) -// * -// * # return g -// */ -// -// /** -// * Return a graph corresponding to a vertex size redistribution. -// * -// * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. -// * -// * More generally, a conversion can be done between different lists of sizes, for some vertex type. -// */ -// redistributer = (domain = list, codomain = list) => { -// -// } -// } -// -// export class CodeView extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// popup_visible = (): Ray => { throw new NotImplementedError(); } -// set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } -// ident_at_cursor = (): Ray => { throw new NotImplementedError(); } -// insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } -// keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } -// set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } -// add_line_below = (text = str): Ray => { throw new NotImplementedError(); } -// } -// -// export class CodeCompletionModel extends Ray { -// __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } -// set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } -// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } -// rowCount = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class ChypDocument extends Ray { -// __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } -// confirm_close = (): Ray => { throw new NotImplementedError(); } -// add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } -// open = (file_name = str): Ray => { throw new NotImplementedError(); } -// save = (): Ray => { throw new NotImplementedError(); } -// save_as = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class Editor extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// title = (): Ray => { throw new NotImplementedError(); } -// reset_state = (): Ray => { throw new NotImplementedError(); } -// invalidate_text = (): Ray => { throw new NotImplementedError(); } -// next_part = (): Ray => { throw new NotImplementedError(); } -// jump_to_error = (): Ray => { throw new NotImplementedError(); } -// show_errors = (): Ray => { throw new NotImplementedError(); } -// show_at_cursor = (): Ray => { throw new NotImplementedError(); } -// next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } -// repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } -// update_state = (): Ray => { throw new NotImplementedError(); } -// import_at_cursor = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class CheckThread extends Ray { -// __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } -// run = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class ErrorListModel extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } -// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } -// headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } -// index = (row = int, column = int): Ray => { throw new NotImplementedError(); } -// columnCount = (): Ray => { throw new NotImplementedError(); } -// rowCount = (): Ray => { throw new NotImplementedError(); } -// parent = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class EItem extends Ray { -// __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } -// paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } -// } -// -// export class VItem extends Ray { -// __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } -// refresh = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class TItem extends Ray { -// __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } -// refresh = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class GraphScene extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } -// add_items = (): Ray => { throw new NotImplementedError(); } -// mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } -// mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } -// mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } -// } -// -// export class GraphView extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } -// } -// -// export class ChypHighlighter extends Ray { -// __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } -// set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } -// highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } -// } -// -// export class MainWindow extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// remove_empty_editor = (): Ray => { throw new NotImplementedError(); } -// update_file_name = (): Ray => { throw new NotImplementedError(); } -// tab_changed = (i = int): Ray => { throw new NotImplementedError(); } -// update_themes = (): Ray => { throw new NotImplementedError(); } -// recent_files = (): Ray => { throw new NotImplementedError(); } -// update_recent_files = (): Ray => { throw new NotImplementedError(); } -// add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } -// close_tab = (): Ray => { throw new NotImplementedError(); } -// new = (): Ray => { throw new NotImplementedError(); } -// open = (): Ray => { throw new NotImplementedError(); } -// save = (): Ray => { throw new NotImplementedError(); } -// save_as = (): Ray => { throw new NotImplementedError(); } -// undo = (): Ray => { throw new NotImplementedError(); } -// redo = (): Ray => { throw new NotImplementedError(); } -// show_errors = (): Ray => { throw new NotImplementedError(); } -// add_rewrite_step = (): Ray => { throw new NotImplementedError(); } -// repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } -// next_rewrite = (): Ray => { throw new NotImplementedError(); } -// next_part = (): Ray => { throw new NotImplementedError(); } -// previous_part = (): Ray => { throw new NotImplementedError(); } -// next_tab = (): Ray => { throw new NotImplementedError(); } -// previous_tab = (): Ray => { throw new NotImplementedError(); } -// goto_import = (): Ray => { throw new NotImplementedError(); } -// closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } -// build_menu = (): Ray => { throw new NotImplementedError(); } -// } -// -// // TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? -// export class Match extends Ray { -// -// get domain(): Graph { throw new NotImplementedError(); } -// get codomain(): Graph { throw new NotImplementedError(); } -// get vertex_map(): Ray { throw new NotImplementedError(); } -// get vertex_image(): Ray { throw new NotImplementedError(); } -// get edge_map(): Ray { throw new NotImplementedError(); } -// get edge_image(): Ray { throw new NotImplementedError(); } -// -// __init__ = (): Ray => { throw new NotImplementedError(); } -// __str__ = (): Ray => { -// // (f'\tVertex map: {str(self.vertex_map)}' -// // + f'\n\tEdge map: {str(self.edge_map)}') -// // TODO -// throw new NotImplementedError(); } -// -// // Implemented on Ray -// // TODO; doesnt copy the graphs at domain/codomain -// // copy = (): Ray => { throw new NotImplementedError(); } -// -// /** -// * Try to map `domain_vertex` to `codomain_vertex`. -// * -// * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. -// * -// * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. -// */ -// try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { -// -// // If the vertex is already mapped, only check the new mapping is consistent with the current match. -// if (this.vertex_map.includes(domain_vertex)) { -// log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) -// return this.vertex_map[domain_vertex] === codomain_vertex; -// } -// -// // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. -// // TODO: This should all be redundant, probably removed ... -// -// // Ensure the mapping preserves vertex type. -// if (domain_vertex.vtype !== codomain_vertex.vtype) { -// log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); -// -// return bool(False); -// } -// -// // Ensure the mapping preserves vertex size. -// if (domain_vertex.size !== codomain_vertex.size) { -// log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) -// return bool(False); -// } -// -// // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. -// if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { -// log('Vertex failed: codomain vertex is boundary but domain vertex is not.') -// return bool(False); -// } -// -// // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. -// if (this.vertex_image.includes(codomain_vertex)) { -// // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. -// if (!domain_vertex.is_boundary()) { -// log('Vertex failed: non-injective on interior vertex.') -// return bool(False); -// } -// -// // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. -// if (this.vertex_image.any(([mapped_vertex, image_vertex]) => -// image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! -// )) { -// log('Vertex failed: non-injective on interior vertex.') -// return bool(False); -// } -// -// return bool(False); -// } -// -// // If a new and consistent map is found, add it to the vertex map of this match. -// this.vertex_map[domain_vertex] = codomain_vertex -// this.vertex_image.add(codomain_vertex) -// -// // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. -// -// if (!domain_vertex.is_boundary()) { -// if (domain_vertex.in_edges.count.as_int() !== codomain_vertex.in_edges.count.as_int()) { -// log('Vertex failed: in_edges cannot satisfy gluing conditions.') -// return bool(False) -// } -// if (domain_vertex.out_edges.count.as_int() !== codomain_vertex.out_edges.count.as_int()) { -// log('Vertex failed: in_edges cannot satisfy gluing conditions.') -// return bool(False) -// } -// } -// -// // If a new consistent map is added that satisfies the gluing conditions, we are successful. -// log('Vertex success.') -// return bool(True); -// } -// -// try_add_edge = (domain_edge = int, codomain_edge = int): Ray => { throw new NotImplementedError(); } -// domain_neighbourhood_mapped = (vertex = int): Ray => { throw new NotImplementedError(); } -// map_scalars = (): Ray => { throw new NotImplementedError(); } -// more = (): Ray => { throw new NotImplementedError(); } -// is_total = (): Ray => { throw new NotImplementedError(); } -// is_surjective = (): Ray => { throw new NotImplementedError(); } -// is_injective = (): Ray => { throw new NotImplementedError(); } -// is_convex = (): Ray => { throw new NotImplementedError(); } -// -// /** -// * TODO Not implemented;; -// * # def cod_nhd_mapped(self, cod_v: int): -// * # """Returns True if nhd(cod_v) is the range of emap""" -// * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and -// * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) -// */ -// } -// -// export class Matches extends Ray { -// __init__ = (domain = Graph, codomain = Graph): Ray => { throw new NotImplementedError(); } -// __iter__ = (): Ray => { throw new NotImplementedError(); } -// __next__ = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class Rule extends Ray { -// get lhs(): Graph { throw new NotImplementedError(); } -// get rhs(): Graph { throw new NotImplementedError(); } -// -// /** -// * TODO: Put the name on each side of the rule, not the '-' hacky thing -// */ -// get name(): Ray { throw new NotImplementedError(); } -// get equiv(): Ray { throw new NotImplementedError(); } -// -// __init__ = (name = str(''), equiv = bool(True)): Ray => { -// // TODO: Maybe just move exception to a method on this thing -// -// if (this.lhs.domain !== this.rhs.domain) // TODO: !== -// throw new RuleError(`Inputs must match on LHS and RHS of rule (${this.rhs.domain} != ${this.lhs.domain})`); -// -// if (this.lhs.codomain !== this.rhs.codomain) -// throw new RuleError(`Outputs must match on LHS and RHS of rule (${this.rhs.codomain} != ${this.lhs.codomain})`) -// -// -// throw new NotImplementedError(); -// -// } -// -// copy = (): Ray => { throw new NotImplementedError(); } -// -// // TODO: Could put this on ray, generalize to swapping -// converse = (): Rule => { -// // TODO remove this hacky thing - just tries to us -a / a -// const name = this.name.as_string().startsWith('-') ? this.name.substring(1) : `-${this.name}`; -// -// const converse: Rule = this.copy().cast(); // TODO equiv=True? -// converse.name = name; -// -// // TODO: Wont work, we just should swap initial/terminal;\ -// //swap?? or change direction.. -// // const swap = converse.rhs; -// // converse.rhs = converse.lhs; -// // converse.lhs = swap; -// return converse; -// } -// -// /** -// * Returns True if boundary on lhs embeds injectively -// */ -// is_left_linear = (): Ray => { -// // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading -// return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() -// .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. -// } -// -// /** -// * Do double-pushout rewriting -// * -// * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. -// * @param match -// */ -// dpo = (match: Match): Ray => { -// // if (!this.is_left_linear()) -// // throw new NotImplementedError("Only left linear rules are supported for now") -// -// const rewritten_graph: Graph = match.codomain.copy(); -// -// // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? -// -// // Computes the push complement ?? (just the thing we're replacing right?) -// // TODO: Removes the match from the copy? -// this.lhs.edges().all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); -// -// const inputs = []; -// const outputs = []; -// -// this.lhs.vertices().all(rule_vertex => { -// const match_vertex = match.vertex_map[rule_vertex]; -// -// if (!this.lhs.is_boundary(rule_vertex)) { -// rewritten_graph.remove_vertex(match_vertex); -// return; -// } -// -// const rule_input = this.lhs.vertex_data(rule_vertex).in_indices; -// const rule_output = this.lhs.vertex_data(rule_vertex).out_indices; -// -// if (rule_input.count.as_int() === 1 && rule_output === 1) { -// const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); -// -// if (match_input.count.as_int() !== 1 && match_output.count.as_int() !== 1) -// throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); -// -// inputs[rule_vertex] = match_input[0]; -// outputs[rule_vertex] = match_output[0]; -// } else if (rule_input.count.as_int() > 1 || rule_output.count.as_int() > 1) { -// throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); -// } -// }) -// -// // Embed Rule.rhs into rewritten_graph -// const replacement = new Match(this.rhs, rewritten_graph); -// -// return replacement; -// } -// -// /** -// * Apply the given rewrite r to at match m and return the first result -// * -// * This is a convience wrapper for `dpo` for when the extra rewrite data isn't needed. -// */ -// rewrite = (match: Match): Graph => { -// // TODO: except StopIteration: -// // raise RuntimeError("Rewrite has no valid context") -// -// const result: Match = this.dpo(match).first().cast(); -// return result.codomain; -// } -// } -// -// export class RewriteState extends Ray { -// __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } -// check = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class State extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } -// part_at = (pos = int): Ray => { throw new NotImplementedError(); } -// var = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// num = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } -// type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } -// id = (items = list(Any)): Ray => { throw new NotImplementedError(); } -// id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } -// eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } -// le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } -// perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } -// size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } -// par = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// color = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// } -// -// export class Tactic extends Ray { -// __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } -// repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } -// error = (message = str): Ray => { throw new NotImplementedError(); } -// has_goal = (): Ray => { throw new NotImplementedError(); } -// global_rules = (): Ray => { throw new NotImplementedError(); } -// lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } -// add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } -// __lhs = (target = str): Ray => { throw new NotImplementedError(); } -// __rhs = (target = str): Ray => { throw new NotImplementedError(); } -// __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } -// __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } -// rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// validate_goal = (): Ray => { throw new NotImplementedError(); } -// lhs = (): Ray => { throw new NotImplementedError(); } -// rhs = (): Ray => { throw new NotImplementedError(); } -// lhs_size = (): Ray => { throw new NotImplementedError(); } -// rhs_size = (): Ray => { throw new NotImplementedError(); } -// highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } -// highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } -// __reset = (): Ray => { throw new NotImplementedError(); } -// next_rhs = (current = str): Ray => { throw new NotImplementedError(); } -// run_check = (): Ray => { throw new NotImplementedError(); } -// name = (): Ray => { throw new NotImplementedError(); } -// check = (): Ray => { throw new NotImplementedError(); } -// make_rhs = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class RuleTac extends Ray { -// name = (): Ray => { throw new NotImplementedError(); } -// make_rhs = (): Ray => { throw new NotImplementedError(); } -// check = (): Ray => { throw new NotImplementedError(); } -// } -// -// export class SimpTac extends Ray { -// name = (): Ray => { throw new NotImplementedError(); } -// __prepare_rules = (): Ray => { throw new NotImplementedError(); } -// make_rhs = (): Ray => { throw new NotImplementedError(); } -// check = (): Ray => { throw new NotImplementedError(); } -// } -// +import {JS, Ray} from "../../explorer/Ray"; +import {NotImplementedError} from "../../explorer/errors/errors"; + +/** + * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. + * GitHub: https://github.com/akissinger/chyp + * + * A simple way of phrasing this conversion, is that the concept of a 'Vertex', 'Edge', 'Graph', 'Rule', ..., 'Rewrite' are merged into one thing: a Ray. + * + * NOTE: + * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. + * + * - The .copy()'s are implemented on Ray. + * + * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. + * + * TODO: Probably want all these types at runtime, to display them + * + * TODO: Graph boundary is automatic with this structure? + * + * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? + * + * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. + * + * TODO: Can just move the terminal which holds the oointer to the boundary + * + * TODO: Automatically generate visual examples of all the methods + * + * TODO: Runtime errors as rays + * + * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph + */ +/** + * TODO: These coordinates used for inferences? + * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" + */ + +export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; + +export const Color = (t1: Ray = str('')): Ray => { throw new NotImplementedError() }; + +export class ValueError extends Error {} + +/** + * Non-default vertex types are identified by a string label + * + * str() | None() - No overloading in TypeScript ;( + */ +export const VType = JS.Iterable([str, None]); + +/** + * An error occurred in the graph backend. + * + * TODO probably hooked as a boolean, one successful the other not + */ +export class GraphError extends Error {} +export class RuleError extends Error {} + +/** + * Used for debugging (the matcher) + */ +const DEBUG = true; // TODO; Generalize +const log = (s: string) => { + if (!DEBUG) + return; + + console.log(s); +} + +/** + * Data associated with a single vertex. + */ +export class VData extends Ray { + // The vertex type. + vtype = this.property('vtype', None); + + // The register size (number of bundled parallel wires) of the vertex. + size = this.count; // Implemented on Ray.count + + // TODO: These infers will probably be removed? + // Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). + infer_type = this.property('infer_type', bool(False)) + // Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). + infer_size = this.property('infer_size', bool(False)) + + // x-coordinate at which to draw the vertex. + x = this.property('y', int(0)) + // y-coordinate at which to draw the vertex. + y = this.property('y', int(0)) + + highlight = this.property('highlight', bool(False)) + value = this.property('value') + + /** + * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. + * + * TODO ; // set[int] = set() + * TODO ; these are just the initial/terminal sides of a Ray. they're just duplicated + */ + get in_edges(): Ray { throw new NotImplementedError(); } + get out_edges(): Ray { throw new NotImplementedError(); } + + /** + * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. + */ + get in_indices(): Ray { return this.initial } // + get out_indices(): Ray { throw new NotImplementedError(); } + + is_input = (): Ray => this.in_indices.count.as_int() > 0; + is_output = (): Ray => this.out_indices.count.as_int() > 0; + is_boundary = (): Ray => this.is_input() || this.is_output(); + + // TODO: Probably generalizable + + /** + * + * @param other + */ + merge = (other: VData): Ray => { + // TODO: other is destroyed + // TODO: Vertices + // this.initial.equivalent(other.initial); + // this.terminal.equivalent(other.initial); + + /* + + vd = self.vertex_data(v) + # print("merging %s <- %s" % (v, w)) + + # Where vertex `w` occurs as an edge target, replace it with `v` + for e in self.in_edges(w): + ed = self.edge_data(e) + ed.t = [v if x == w else x for x in ed.t] + vd.in_edges.add(e) + + # Where vertex `w` occurs as an edge source, replace it with `v` + for e in self.out_edges(w): + ed = self.edge_data(e) + ed.s = [v if x == w else x for x in ed.s] + vd.out_edges.add(e) + + # Wherever `w` occurs on the graph boundary, replace it with `v` + self.set_inputs([v if x == w else x for x in self.inputs]) + self.set_outputs([v if x == w else x for x in self.outputs]) + + # Remove references to `w` from the graph + self.remove_vertex(w) + + */ + + throw new NotImplementedError(); + } + + fresh = (): VData => { + // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. + + // vtype=vd.vtype, size=vd.size, + // x=vd.x, y=vd.y, value=vd.value + + } + + // TODO: Shouldn't be here, this should be implemented on Ray if it's general enough + get domain(): Ray { return JS.Iterable([this.vtype, this.size]) }; + +} + +/** + * Data associated with a single edge. + */ +export class EData extends Ray { + + get source() { return this.s }; + get target() { return this.t }; + + // TODO: this is just the initial frame + get s(): Ray { throw new NotImplementedError(); } + // TODO: this is just the terminal frame + get t(): Ray { throw new NotImplementedError(); } + + fg = this.property('bg', Color()); + bg = this.property('bg', Color()); + x = this.property('y', int(0)); + // y-coordinate at which to draw the vertex. + y = this.property('y', int(0)); + highlight = this.property('highlight', bool(False)) + hyper = this.property('value', bool(True)) + value = this.property('value') + + __repr__ = (): Ray => { throw new NotImplementedError(); + // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' + } + + // TODO: More stuff to relate it to the screen that shouldnt be here. + /** + * Return how many width 'units' this box needs to display nicely. + * + * This uses a simple rule: + * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. + * - Otherwise draw as a larger (size 2) box. + */ + box_size = (): Ray => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); + + domain = (): Ray => this.source.cast().domain; + codomain = (): Ray => this.target.cast().domain; + + toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL +} + +/** + * A hypergraph with boundaries. + * + * This is the main data structure used by Chyp. It represents a directed + * hypergraph (which we call simply a "graph") as two dictionaries for + * vertices and (hyper)edges, respectively. Each vertex is associated with a + * `VData` object and edge edge with an `EData` object, which stores + * information about adjacency, position, label, etc. + * + * The particular flavor of hypergraphs we use associate to each hyperedge a + * list of source vertices and a list of target vertices. The hypergraph + * itself also has a list of input vertices and a list of output vertices, + * which are used for sequential composition and rewriting. + */ +export class Graph extends Ray { + + get vindex(): Ray { return this.vdata.index.max(0); } + get eindex(): Ray { return this.edata.index.max(0); } + + // Mapping from integer identifiers of each vertex to its data. + vdata = this.property('vertices'); + // Mapping from integer identifiers of each hyperedge to its data. + edata = this.property('edges'); + + // TODO .keys + vertices = this.property('vertices'); + edges = this.property('edges'); + + /** + * Return the domain of the graph. + * + * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. + */ + // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. + get domain(): Ray { return this.inputs.cast().domain; }; + + /** + * Return the domain of the graph. + * + * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. + */ + get codomain(): Ray { return this.outputs.cast().domain; }; + + vertex_data = (v = int): VData => this.vertices().at(v).cast(); + edge_data = (e = int): EData => this.edges().at(e).cast(); + + // TODO: Shouldnt be here + ___next_index = (name = int(-1), index: Ray): Ray => { + // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) + const current = name === -1 ? index : Math.max(name, index); + return current + 1; + } + + /** + * Add a new vertex to the graph. + * + * @param name The value carried by this vertex (currently unused). + * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. + * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). + */ + add_vertex = (name = int(-1), vertex: VData): VData => { + this.vindex = this.___next_index(name, this.vindex); + + this.vdata[this.vindex - 1] = vertex; + return vertex; + } + + /** + * Add a new hyperedge to the graph. + * + * @param s + * @param t + */ + add_edge = (name = int(-1), edge: EData): EData => { + this.eindex = this.___next_index(name, this.eindex); + + this.edata[this.eindex - 1] = edge; + + // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) + // for v in s: + // self.vdata[v].out_edges.add(e) + // for v in t: + // self.vdata[v].in_edges.add(e) + + return edge; + } + // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. + + /** + * Remove a vertex from the graph. + * + * This removes a single vertex. + * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. + * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. + * + * @param v + * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. + */ + remove_vertex = (v = int, strict: boolean = false): Ray => { + // TODO: destroy any reference of it (could just do this lazy) + // TODO: as delegation + + if (strict) { + if (this.vertex_data(v).in_edges.count.as_int() > 0 || this.vertex_data(v).out_edges > 0) { + throw new ValueError('Attempting to remove vertex with adjacent' + + 'edges while strict == True.'); + } + + if (this.inputs.includes(v) || this.outputs.includes(v)) { + throw new ValueError('Attempting to remove boundary vertex while' + + 'strict == True.'); + + }// TODO CAN BE SIMPLIFIED + } + + // in/out edges from all vertices + delete this.vdata[v]; + } + + /** + * Remove an edge from the graph. + * + * @param e Integer identifier of the edge to remove. + */ + remove_edge = (e = int): Ray => { + // TODO: destroy any reference of it (could just do this lazy) + // in/out edges from all vertices + delete this.edata[e]; + } + + // TODO: Can these be overlaoded in properties using -=, += in TS? + + /** + * Append `inp` to the inputs of the graph. + * + * @param inp The list of vertex integer identifiers of the appended inputs. + */ + add_inputs = (inp = list(int)): Ray => { + this.inputs.continues_with(inp); // TODO: Perhaps splat + } + /** + * Append `outp` to the outputs of the graph. + * + * @param outp The list of vertex integer identifiers of the appended outputs. + */ + add_outputs = (outp = list(int)): Ray => { + this.outputs.continues_with(outp); // TODO: Perhaps splat + } + // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) + + + // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. + + // Return the list of vertex ids of the graph inputs. + get inputs(): Ray { throw new NotImplementedError(); } + // Return the list of vertex ids of the graph outputs. + get outputs(): Ray { throw new NotImplementedError(); } + + // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs + set inputs(ray = list(int)) { throw new NotImplementedError(); } + set outputs(ray = list(int)) { throw new NotImplementedError(); } + + // TODO: Move these to a "reference-like" structure, need to be on VData.. + + /** + * These are all just slightly differently abstracted in TypeScript here to make them a little more native. + */ + set_inputs = (inp = list(int)): Ray => this.inputs = inp; + set_outputs = (outp = list(int)): Ray => this.outputs = outp; + + /** + * All these are just delegations from some Vertex/Edge structure. + */ + // .vertices + num_vertices = (): Ray => this.vertices().count.as_int(); + + // .edges + num_edges = (): Ray => this.edges().count.as_int(); + + // .vertex_data + is_input = (v = int): Ray => this.vertex_data(v).is_input(); + is_output = (v = int): Ray => this.vertex_data(v).is_output(); + is_boundary = (v = int): Ray => this.vertex_data(v).is_boundary(); + in_edges = (v = int): Ray => this.vertex_data(v).in_edges; + out_edges = (v = int): Ray => this.vertex_data(v).out_edges; + + // .edge_data + source = (e = int): Ray => this.edge_data(e).source; + target = (e = int): Ray => this.edge_data(e).target; + edge_domain = (edge_id = int): Ray => this.edge_data(edge_id).domain(); + edge_codomain = (edge_id = int): Ray => this.edge_data(edge_id).codomain(); + + /** + * Return vertices that lie on a directed path from any of `vs`. + * // TODO: Just traverse the rays, deduplicate using the index + */ + successors = (ray: Ray): Ray => ray.next; + + /** + * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. + * + * @param v Integer identifier of the vertex into which to merge `w`. + * @param w Integer identifier of the vertex to merge into `v`. + */ + merge_vertices = (v = int, w = int): Ray => this.vertex_data(v).merge(this.vertex_data(w)); + + /** + * Split a vertex into copies for each input, output, and tentacle. + * + * This is used for computing pushout complements of rules that aren't left-linear. + * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). + * + * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. + * + * @param v Integer identifier of vertex to be exploded. + */ + explode_vertex = (v = int): Ray => { + const vertex = this.vertex_data(v); + + // TODO; This just seems like another copy which minor changes + + const next_inputs = empty(); + const next_outputs = empty(); + + const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process + vertex: VData, + boundary: (vertex: VData) => Ray, + next_boundary: Ray + ) => { + // TODO: It's just a duplicated process for vertex/edge since their definition is separataed + + // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. + // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs]) + // TODO: Basically a copy, and replace this one vertex + + // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. + boundary(vertex).all(e => { + const edge: EData = e.cast(); + + edge.t = edge.t + .map(target => { + if (target === v) + return target; + + const fresh_vertex = vertex.fresh(); + next_boundary.add(this.add_vertex(fresh_vertex)) + boundary(fresh_vertex).add(edge); + }) + }); + + } + + // TODO: It's always just duplicated for both ends, + __temp(vertex, (vertex) => vertex.in_edges, next_inputs); + __temp(vertex, (vertex) => vertex.out_edges, next_outputs); + + // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. + vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal + vertex.out_edges.clear(); + + // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). + this.remove_vertex(vertex, true); + + return [next_inputs, next_outputs]; + } + + + /** + * Insert a new identity hyperedge after the given vertex. + * + * A new vertex is also created, which replaces the original vertex as the source of any edges in graph as well as any occurrences of the original vertex in the graph outputs. + * + * @param reverse + * - If `False`, the original vertex becomes the source of the ew identity hyperedge while the new vertex becomes the target. + * - If `True`, the source and target of the new identity are flipped. This can be used to break directed cycles, by neffectively introducing a cap and cup. + */ + insert_id_after = (v = int, reverse = bool(False)): Ray => { + const vertex = this.vertex_data(v); + + // Create a new vertex with the same vtype and size + // //TODO ; Which is this .fresh + const new_vertex = vertex.fresh(); + new_vertex.x += 3; + // The new vertex is highlighted whenever the orignal vertex is. + new_vertex.highlight = vertex.highlight; // TODO: This not done by .fresh? + + /** + * //TODO: BEcause it's inserted after, set the output (generalize to just moving the reference to the terminal. + * # Replace any occurences of the original vertex in the graph outputs + * # with the new vertex. + * self.set_outputs([x if x != v else w for x in self.outputs()]) + */ + + // Where the original vertex is the source of a hyperedge, replace it with the new vertex and register this change with the data instance of each vertex + // TODO syncs the out_edges fields, wd.out_edges.add(e) vd.out_edges.clear() + // TODO replace out_edges.source to new_vertex again + + // Assign the orignal and new vertex as source or target of the new identity edge, based on the `reverse` argument. + // TODO: Sets reverse just flipping around the initial/terminal.. + // TODO: s, t = ([v], [w]) if not reverse else ([w], [v]) + + // Create the new identity edge. + const edge = this.add_edge() // s, t, 'id', vd.x + 1.5, vd.y) + edge.hightlight = vertex.highlight; // The new edge is highlighted whenever the original vertex is. + + return edge; + } + + /** + * Take the monoidal product of this graph in-place with another. + * + * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. + * + * @param other + * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. + */ + tensor = (other: Graph, layout: boolean = true): Ray => { + + const a = this; + const b = other; + + const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] + + tensor.initial.any.y -= + tensor.initial.any.y.max(); // max_self + + tensor.terminal.any.y -= + (layout ? tensor.terminal.any.y.min() : 0) + 1; // min_other TODO: Why + 1 ? + + /** + * # self.set_inputs(self.inputs + [vmap[v] for v in other.inputs]) + * # self.set_outputs(self.outputs + [vmap[v] for v in other.outputs]) + * + * # Add the inputs and outputs of the other graph to this one. + * self.add_inputs([vmap[v] for v in other.inputs]) + * self.add_outputs([vmap[v] for v in other.outputs]) + */ + // TODO: Add equivalence/reference on the inputs/output extremes. + } + + /** + * Sequentially compose this graph in-place with another. + * + * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. + */ + compose = (other: Graph): Ray => { + // TODO Just matching outputs and inputs.. + + const a = this; + const b = other; + + // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" + const compose: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] + + // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. + + // TODO: This is just again an equivalence type check on the ends of the ray + + // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs + + { + if (compose.initial.count.as_int() !== compose.terminal.count.as_int()) + throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed + + /** + * for output_id, input_id in zip(self_outputs, other_inputs): + * output_data = self.vertex_data(output_id) + * input_data = other.vertex_data(input_id) + * if output_data.vtype != input_data.vtype: + * if not (output_data.infer_type or input_data.infer_type): + * raise GraphError( + * f'Codomain {self.codomain()} does not ' + * + f'match domain {other.domain()}' + * ) + * if output_data.size != input_data.size: + * if not (output_data.infer_size or input_data.infer_size): + * raise GraphError( + * f'Codomain {self.codomain()} does not ' + * + f'match domain {other.domain()}' + * ) + */ + } + + /** + * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. + */ + + // Compute the max x-coordinate of the edges and vertices in this graph. + + // TODO: Again, recursively going through everything defined on the initial side (outputs) + // Shift all vertices and edges of this graph below the x-axis. + compose.initial.any.x -= + compose.initial.any.x.max(); // max_self + + // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] + compose.terminal.any.x -= + compose.terminal.any.x.min(); // min_other + + // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. + /** + * plug1 = self.outputs + * plug2 = [vmap[v] for v in other.inputs] + * + * if len(plug1) != len(plug2): + * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' + * + f'outputs into one with {len(plug2)} inputs') + * + * self.set_outputs([vmap[v] for v in other.outputs]) + */ + + // [outputs to inputs] + // Go through pairs of vertices from each plug + compose.zip().all(([input, output]) => { + /** + * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. + */ + + // TODO: does this ever happen??? + // while p1 in quotient: + // p1 = quotient[p1] + // while p2 in quotient: + // p2 = quotient[p2] + + + // TODO, Again the same equivalence check for loops etc.. + { + // If the resulting p1 and p2 are not the same vertex, merge them. + if (input === output) + return; + + // TODO; DO this on the vertices; + // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) + + // If both vertices have flexible types that are not equal, raise an error due to ambiguity. + // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. + + + // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. + + ['vtype', 'size'].forEach(structure => { + const infer = `infer_${structure}`; + + if (input[infer] && output[infer] && input[structure] !== output[structure]) { + throw GraphError(`Ambiguous vertex ${structure} during composition.`) + + } else if (input[infer]) { + // Otherwise, if one vertex has a flexible type, ensure the vertex types match. + // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it + // TODO: Again both sides same thing.. + input[structure] = output[structure]; // TODO: Generalized structure + input[infer] = false; + } else if (output.infer_type) { + output[structure] = input[structure]; + output[infer] = false; + } + }); + + input.merge(output); + // # Register than p2 has been merged into p1. + // quotient[p2] = p1 + } + }); + } + + /** + * Return the tensor product of this graph with another. + * + * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them + */ + __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); + + /** + * Return the composition of the current graph with `other`. + * + * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. + * @param other + */ + __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); + + /** + * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer + */ + ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { + const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. + something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? + return a_copy; // Could generalize to either end + } + + /** + * Set the `highlight` flag for a set of vertices and edges. + * + * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. + * + * @param vertices A set of vertices to highlight. + * @param edges A set of edges to highlight. + */ + highlight = (vertices = set(int), edges = set(int)): Ray => { + // TODO Again, these could be merged + this.vdata + .filter(vertex => vertices.includes(vertex)) + .all(vertex => vertex.cast().highlight = bool(true)); + this.edata + .filter(edge => edges.includes(edge)) + .all(edge => edge.cast().highlight = bool(true)); + + + } + + /** + * Clear the `highlight` flag for all vertices/edges. + * + * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. + */ + unhighlight = (): Ray => { + // TODO: These could be merged + this.vdata.highlight = false; + this.edata.highlight = false; + } +} + +export class Chyp extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + + /** + * Load a .chyp graph file from the given path. + */ + load_graph = (path = str) => { + // TODO: From localStorage for now? + // with open(path) as f: + // g = graph_from_json(f.read()) + } + + /** + * Return a graph corresponding to the identity map. + * + * This graph has a single vertex which is both an input and an output. + */ + identity = (vertex: VData): Graph => { + const graph = new Graph(); + + vertex.x = 0; // TODO automatic>? + vertex.y = 0; + graph.add_vertex(int(-1), vertex); + // TODO synce input/output automatically? + // g.set_inputs([v]) + // g.set_outputs([v]) + + return graph; + } + + + ___map_domain = (domain: Ray, _default: VData): Ray => { + return domain.map(([vtype, size], i) => { + const vertex: VData = _default.copy().cast(); + // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere + vertex.x = -1.5; + vertex.y = i - (i-1) / 2; + + return vertex; + }) + } + + /** + * Return a graph with one hyperedge and given domain and codomain. + * + * @param _default + * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. + * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. + */ + gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { + const graph = new Graph(); + + const inputs = this.___map_domain(domain, _default) + .map(vertex => graph.add_vertex(vertex)); + const outputs = this.___map_domain(codomain, _default) + .map(vertex => graph.add_vertex(vertex)); + + // TODO This is probably automatic at some point, remove + const edge = new EData(); + edge.s = inputs; + edge.t = outputs; + graph.add_edge(int(-1), edge); + // g.set_inputs(inputs) + // g.set_outputs(outputs) + + return graph; + } + + /** + * Return a graph corresponding to the given permutation. + * + * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. + * + * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. + * + * @param p A permutation given as an n-element list of integers from 0 to n-1. + * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. + */ + perm = (p = list(int), domain: Ray, _default: VData) => { + + const graph = new Graph(); + const num_wires = p.count.as_int(); + + if (num_wires !== domain.count.as_int()) + throw new GraphError(`Domain ${domain} does not match length of permutation.`) + + // TODO use ___map_domain + const inputs = domain.map(([vtype, size], i) => { + const vertex: VData = _default.copy().cast(); + // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere + vertex.x = 0; + vertex.y = i - (num_wires - 1) / 2; + + return vertex; + }) + .map(vertex => graph.add_vertex(vertex)); + // const outputs = num_wires.range(i => [inputs[p[i]]) + + // TODO Should be automatic + // g.set_inputs(inputs) + // g.set_outputs(outputs) + return graph; + } + + graph_from_json = (json_string = str): Graph => { + const json = JSON.parse(json_string().as_string()); // TODO + + const graph = new Graph(); + + // TODO: Don't do this so naively + // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), + // y=float(vd["y"] if "y" in vd else 0.0), + // value=vd["value"] if "value" in vd else "", + // name=int(v)) + // for e, ed in j["edges"].items(): + // g.add_edge(s=[int(v) for v in ed["s"]], + // t=[int(v) for v in ed["t"]], + // value=ed["value"] if "value" in ed else "", + // x=float(ed["x"]) if "x" in ed else 0.0, + // y=float(ed["y"]) if "y" in ed else 0.0, + // hyper=bool(ed["hyper"]) if "hyper" in ed else True, + // name=int(e)) + // + // g.set_inputs([int(v) for v in j["inputs"]]) + // g.set_outputs([int(v) for v in j["outputs"]]) + // json.vertices.forEach(((vertex, i) => graph.add_vertex( + // i, + // new VData() + // )); + + return graph; + } + + /** + * # def wide_id() -> Graph: + * # return gen("id", 1, 1) + * + * # def id_perm(p: List[int]) -> Graph: + * # g = Graph() + * # size = len(p) + * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] + * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] + * + * # for i in range(size): + * # y = i - (size-1)/2 + * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) + * + * # g.set_inputs(inputs) + * # g.set_outputs(outputs) + * + * # return g + */ + + /** + * Return a graph corresponding to a vertex size redistribution. + * + * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. + * + * More generally, a conversion can be done between different lists of sizes, for some vertex type. + * + * @param domain A list of pairs (vertex type, register size) corresponding to each input vertex. + * @param codomain A list of pairs (vertex type, register size) corresponding to each output vertex. + */ + redistributer = (domain = list, codomain = list) => { + /** + * vtypes = set(vtype for vtype, _ in domain) + * vtypes.update(vtype for vtype, _ in codomain) + * if len(vtypes) > 1: + * raise GraphError('Size conversion cannot mix vertex types.') + * + * # Raise error if size conservation is violated + * domain_size = sum(size for _, size in domain) + * codomain_size = sum(size for _, size in codomain) + * if domain_size != codomain_size: + * raise GraphError(f'Sum of domain sizes ({domain_size}) does not equal' + * + f'sum of codomain sizes ({codomain_size}).') + * + * return gen('_redistributer', domain, codomain) + */ + + } +} + +export class CodeView extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + popup_visible = (): Ray => { throw new NotImplementedError(); } + set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } + ident_at_cursor = (): Ray => { throw new NotImplementedError(); } + insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } + keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } + set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } + add_line_below = (text = str): Ray => { throw new NotImplementedError(); } +} + +export class CodeCompletionModel extends Ray { + __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } + set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } + data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } + rowCount = (): Ray => { throw new NotImplementedError(); } +} + +export class ChypDocument extends Ray { + __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } + confirm_close = (): Ray => { throw new NotImplementedError(); } + add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } + open = (file_name = str): Ray => { throw new NotImplementedError(); } + save = (): Ray => { throw new NotImplementedError(); } + save_as = (): Ray => { throw new NotImplementedError(); } +} + +export class Editor extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + title = (): Ray => { throw new NotImplementedError(); } + reset_state = (): Ray => { throw new NotImplementedError(); } + invalidate_text = (): Ray => { throw new NotImplementedError(); } + next_part = (): Ray => { throw new NotImplementedError(); } + jump_to_error = (): Ray => { throw new NotImplementedError(); } + show_errors = (): Ray => { throw new NotImplementedError(); } + show_at_cursor = (): Ray => { throw new NotImplementedError(); } + next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } + repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } + update_state = (): Ray => { throw new NotImplementedError(); } + import_at_cursor = (): Ray => { throw new NotImplementedError(); } +} + +export class CheckThread extends Ray { + __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } + run = (): Ray => { throw new NotImplementedError(); } +} + +export class ErrorListModel extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } + data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } + headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } + index = (row = int, column = int): Ray => { throw new NotImplementedError(); } + columnCount = (): Ray => { throw new NotImplementedError(); } + rowCount = (): Ray => { throw new NotImplementedError(); } + parent = (): Ray => { throw new NotImplementedError(); } +} + +export class EItem extends Ray { + __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } + paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } +} + +export class VItem extends Ray { + __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } + refresh = (): Ray => { throw new NotImplementedError(); } +} + +export class TItem extends Ray { + __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } + refresh = (): Ray => { throw new NotImplementedError(); } +} + +export class GraphScene extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } + add_items = (): Ray => { throw new NotImplementedError(); } + mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } + mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } + mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } +} + +export class GraphView extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } +} + +export class ChypHighlighter extends Ray { + __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } + set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } + highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } +} + +export class MainWindow extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + remove_empty_editor = (): Ray => { throw new NotImplementedError(); } + update_file_name = (): Ray => { throw new NotImplementedError(); } + tab_changed = (i = int): Ray => { throw new NotImplementedError(); } + update_themes = (): Ray => { throw new NotImplementedError(); } + recent_files = (): Ray => { throw new NotImplementedError(); } + update_recent_files = (): Ray => { throw new NotImplementedError(); } + add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } + close_tab = (): Ray => { throw new NotImplementedError(); } + new = (): Ray => { throw new NotImplementedError(); } + open = (): Ray => { throw new NotImplementedError(); } + save = (): Ray => { throw new NotImplementedError(); } + save_as = (): Ray => { throw new NotImplementedError(); } + undo = (): Ray => { throw new NotImplementedError(); } + redo = (): Ray => { throw new NotImplementedError(); } + show_errors = (): Ray => { throw new NotImplementedError(); } + add_rewrite_step = (): Ray => { throw new NotImplementedError(); } + repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } + next_rewrite = (): Ray => { throw new NotImplementedError(); } + next_part = (): Ray => { throw new NotImplementedError(); } + previous_part = (): Ray => { throw new NotImplementedError(); } + next_tab = (): Ray => { throw new NotImplementedError(); } + previous_tab = (): Ray => { throw new NotImplementedError(); } + goto_import = (): Ray => { throw new NotImplementedError(); } + closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } + build_menu = (): Ray => { throw new NotImplementedError(); } +} + +// TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? +export class Match extends Ray { + + get domain(): Graph { throw new NotImplementedError(); } + get codomain(): Graph { throw new NotImplementedError(); } + get vertex_map(): Ray { throw new NotImplementedError(); } + get vertex_image(): Ray { throw new NotImplementedError(); } + get edge_map(): Ray { throw new NotImplementedError(); } + get edge_image(): Ray { throw new NotImplementedError(); } + + __init__ = (): Ray => { throw new NotImplementedError(); } + __str__ = (): Ray => { + // (f'\tVertex map: {str(self.vertex_map)}' + // + f'\n\tEdge map: {str(self.edge_map)}') + // TODO + throw new NotImplementedError(); } + + // Implemented on Ray + // TODO; doesnt copy the graphs at domain/codomain + // copy = (): Ray => { throw new NotImplementedError(); } + + /** + * Try to map `domain_vertex` to `codomain_vertex`. + * + * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. + * + * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. + */ + try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { + + // If the vertex is already mapped, only check the new mapping is consistent with the current match. + if (this.vertex_map.includes(domain_vertex)) { + log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) + return this.vertex_map[domain_vertex] === codomain_vertex; + } + + // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. + // TODO: This should all be redundant, probably removed ... + + // Ensure the mapping preserves vertex type. + if (domain_vertex.vtype !== codomain_vertex.vtype) { + log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); + + return bool(False); + } + + // Ensure the mapping preserves vertex size. + if (domain_vertex.size !== codomain_vertex.size) { + log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) + return bool(False); + } + + // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. + if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { + log('Vertex failed: codomain vertex is boundary but domain vertex is not.') + return bool(False); + } + + // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. + if (this.vertex_image.includes(codomain_vertex)) { + // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. + if (!domain_vertex.is_boundary()) { + log('Vertex failed: non-injective on interior vertex.') + return bool(False); + } + + // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. + if (this.vertex_image.any(([mapped_vertex, image_vertex]) => + image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! + )) { + log('Vertex failed: non-injective on interior vertex.') + return bool(False); + } + + return bool(False); + } + + // If a new and consistent map is found, add it to the vertex map of this match. + this.vertex_map[domain_vertex] = codomain_vertex + this.vertex_image.add(codomain_vertex) + + // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. + + if (!domain_vertex.is_boundary()) { + if (domain_vertex.in_edges.count.as_int() !== codomain_vertex.in_edges.count.as_int()) { + log('Vertex failed: in_edges cannot satisfy gluing conditions.') + return bool(False) + } + if (domain_vertex.out_edges.count.as_int() !== codomain_vertex.out_edges.count.as_int()) { + log('Vertex failed: in_edges cannot satisfy gluing conditions.') + return bool(False) + } + } + + // If a new consistent map is added that satisfies the gluing conditions, we are successful. + log('Vertex success.') + return bool(True); + } + + try_add_edge = (domain_edge = int, codomain_edge = int): Ray => { throw new NotImplementedError(); } + domain_neighbourhood_mapped = (vertex = int): Ray => { throw new NotImplementedError(); } + map_scalars = (): Ray => { throw new NotImplementedError(); } + more = (): Ray => { throw new NotImplementedError(); } + is_total = (): Ray => { throw new NotImplementedError(); } + is_surjective = (): Ray => { throw new NotImplementedError(); } + is_injective = (): Ray => { throw new NotImplementedError(); } + is_convex = (): Ray => { throw new NotImplementedError(); } + + /** + * TODO Not implemented;; + * # def cod_nhd_mapped(self, cod_v: int): + * # """Returns True if nhd(cod_v) is the range of emap""" + * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and + * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) + */ +} + +export class Matches extends Ray { + __init__ = (domain = Graph, codomain = Graph): Ray => { throw new NotImplementedError(); } + __iter__ = (): Ray => { throw new NotImplementedError(); } + __next__ = (): Ray => { throw new NotImplementedError(); } +} + +export class Rule extends Ray { + get lhs(): Graph { throw new NotImplementedError(); } + get rhs(): Graph { throw new NotImplementedError(); } + + /** + * TODO: Put the name on each side of the rule, not the '-' hacky thing + */ + get name(): Ray { throw new NotImplementedError(); } + get equiv(): Ray { throw new NotImplementedError(); } + + __init__ = (name = str(''), equiv = bool(True)): Ray => { + // TODO: Maybe just move exception to a method on this thing + + if (this.lhs.domain !== this.rhs.domain) // TODO: !== + throw new RuleError(`Inputs must match on LHS and RHS of rule (${this.rhs.domain} != ${this.lhs.domain})`); + + if (this.lhs.codomain !== this.rhs.codomain) + throw new RuleError(`Outputs must match on LHS and RHS of rule (${this.rhs.codomain} != ${this.lhs.codomain})`) + + + throw new NotImplementedError(); + + } + + copy = (): Ray => { throw new NotImplementedError(); } + + // TODO: Could put this on ray, generalize to swapping + converse = (): Rule => { + // TODO remove this hacky thing - just tries to us -a / a + const name = this.name.as_string().startsWith('-') ? this.name.substring(1) : `-${this.name}`; + + const converse: Rule = this.copy().cast(); // TODO equiv=True? + converse.name = name; + + // TODO: Wont work, we just should swap initial/terminal;\ + //swap?? or change direction.. + // const swap = converse.rhs; + // converse.rhs = converse.lhs; + // converse.lhs = swap; + return converse; + } + + /** + * Returns True if boundary on lhs embeds injectively + */ + is_left_linear = (): Ray => { + // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading + return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() + .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. + } + + /** + * Do double-pushout rewriting + * + * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. + * @param match + */ + dpo = (match: Match): Ray => { + // if (!this.is_left_linear()) + // throw new NotImplementedError("Only left linear rules are supported for now") + + const rewritten_graph: Graph = match.codomain.copy(); + + // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? + + // Computes the push complement ?? (just the thing we're replacing right?) + // TODO: Removes the match from the copy? + this.lhs.edges.all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); + + const inputs = []; + const outputs = []; + + this.lhs.vertices.all(rule_vertex => { + const match_vertex = match.vertex_map[rule_vertex]; + + if (!this.lhs.is_boundary(rule_vertex)) { + rewritten_graph.remove_vertex(match_vertex); + return; + } + + const rule_input = this.lhs.vertex_data(rule_vertex).in_indices; + const rule_output = this.lhs.vertex_data(rule_vertex).out_indices; + + if (rule_input.count.as_int() === 1 && rule_output === 1) { + const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); + + if (match_input.count.as_int() !== 1 && match_output.count.as_int() !== 1) + throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); + + inputs[rule_vertex] = match_input[0]; + outputs[rule_vertex] = match_output[0]; + } else if (rule_input.count.as_int() > 1 || rule_output.count.as_int() > 1) { + throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); + } + }) + + // Embed Rule.rhs into rewritten_graph + const replacement = new Match(this.rhs, rewritten_graph); + + // TODO: This is probably another of these geeneral patterns, same thing on either ends composed as a single ray., + const input = new Ray(); // [this.lhs.inputs, this.rhs.inputs] + + // first map the inputs, using the matching of the lhs + input.zip().all(([initial, terminal]) => { + match.vertex_map[terminal] = inputs.includes(initial) ? inputs[initial] : match.vertex_map[initial]; + }); + + const output = new Ray(); // [this.lhs.outputs, this.rhs.outputs] + + // next map the outputs. if the same vertex is an input and an output in r.rhs, then merge them in h. + output.zip().all(([initial, terminal]) => { + // TODO: Again, both ends are very similar, there should probably be a direct flip in these, small difference at the end + const temp = outputs.includes(initial) ? outputs[initial] : match.vertex_map[initial]; + + if (match.vertex_map.includes(terminal)) { + rewritten_graph.merge_vertices(match.vertex_map[terminal], temp) + } else { + match.vertex_map[terminal] = temp; + } + }); + + // then map the interior to new, fresh vertices + this.rhs.vertices + .filter(vertex => !vertex.is_boundary()) + .all((vertex: VData) => { + // TODO Again the fresh thing repeated here - just because it's moving between graphs + const new_vertex = rewritten_graph.add_vertex(vertex.fresh()); + + match.vertex_map[vertex] = new_vertex; + match.vertex_image.add(new_vertex); + }); + + // now add the edges from rhs to h and connect them using vmap1 + // TODO: Again this should be the same thing as the vertices + this.rhs.edges. + all((edge: EData) => { + const new_edge = rewritten_graph.add_edge(); + /** + * e1 = h.add_edge([m1.vertex_map[v] for v in ed.s], + * [m1.vertex_map[v] for v in ed.t], + * ed.value, ed.x, ed.y, ed.fg, ed.bg, ed.hyper) + */ + + match.edge_map[edge] = new_edge; + match.edge_image.add(new_edge); + }) + + return replacement; + } + + /** + * Apply the given rewrite r to at match m and return the first result + * + * This is a convience wrapper for `dpo` for when the extra rewrite data isn't needed. + */ + rewrite = (match: Match): Graph => { + // TODO: except StopIteration: + // raise RuntimeError("Rewrite has no valid context") + + const result: Match = this.dpo(match).first().cast(); + return result.codomain; + } +} + +export class RewriteState extends Ray { + __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } +} + +export class State extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } + part_at = (pos = int): Ray => { throw new NotImplementedError(); } + var = (items = List(Any)): Ray => { throw new NotImplementedError(); } + module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } + num = (items = List(Any)): Ray => { throw new NotImplementedError(); } + type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } + type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } + id = (items = list(Any)): Ray => { throw new NotImplementedError(); } + id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } + eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } + le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } + perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } + size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } + par = (items = List(Any)): Ray => { throw new NotImplementedError(); } + gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } + color = (items = List(Any)): Ray => { throw new NotImplementedError(); } + import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } + tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } + nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } +} + +export class Tactic extends Ray { + __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } + repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } + error = (message = str): Ray => { throw new NotImplementedError(); } + has_goal = (): Ray => { throw new NotImplementedError(); } + global_rules = (): Ray => { throw new NotImplementedError(); } + lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } + add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } + add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } + __lhs = (target = str): Ray => { throw new NotImplementedError(); } + __rhs = (target = str): Ray => { throw new NotImplementedError(); } + __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } + __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } + rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } + rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } + rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } + rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } + validate_goal = (): Ray => { throw new NotImplementedError(); } + lhs = (): Ray => { throw new NotImplementedError(); } + rhs = (): Ray => { throw new NotImplementedError(); } + lhs_size = (): Ray => { throw new NotImplementedError(); } + rhs_size = (): Ray => { throw new NotImplementedError(); } + highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } + highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } + __reset = (): Ray => { throw new NotImplementedError(); } + next_rhs = (current = str): Ray => { throw new NotImplementedError(); } + run_check = (): Ray => { throw new NotImplementedError(); } + name = (): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } + make_rhs = (): Ray => { throw new NotImplementedError(); } +} + +export class RuleTac extends Ray { + name = (): Ray => { throw new NotImplementedError(); } + make_rhs = (): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } +} + +export class SimpTac extends Ray { + name = (): Ray => { throw new NotImplementedError(); } + __prepare_rules = (): Ray => { throw new NotImplementedError(); } + make_rhs = (): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } +} + diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 4db3444..1df9f94 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -128,6 +128,7 @@ const Interface = () => { } + const DEBUG = true; const debug: DebugResult = {}; @@ -150,6 +151,8 @@ const Interface = () => { const group_index = (l: string): number => groups.indexOf(group(l)); const index_in_group = (l: string): number => group(l).indexOf(l); + + //TODO: do the same for group in initial/yerminal return <> {/*
*/} {_.values(debug).map(((_ray, index) => { From 77fbfce58c12ad5587b9cf522875c8b9cc4c1fe5 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 14:19:59 +0100 Subject: [PATCH 037/138] 2024/02/10 - More naive translations --- src/@orbitmines/external/chyp/Chyp.ts | 184 +++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 5 deletions(-) diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index a516426..fc85408 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -754,6 +754,46 @@ export class Graph extends Ray { this.vdata.highlight = false; this.edata.highlight = false; } + + /** + * Return matches of domain into codomain. + */ + match = (other: Graph, convex: boolean = true): Matches => new Matches(this, other, convex); + + /** + * Return an isomorphism between graphs g and h if found, otherwise `None`. + * + * If found, the isomorphism is returned as a :py:class:`Matches` instance, whose vertex and edge maps are bijections. + */ + find_iso = (other: Graph): Match => { // TODO | NONE + + // TODO: Again, more equivalence checks + // First, check the domains and codomains are equal between the two graphs. + if (this.domain !== other.domain || this.codomain !== other.codomain) + return None; //TODO + + // Try to find an initial match mapping one of the boundary vertices of the domain graph to the corresponding boundary vertex (the vertex in the same input/output location) of the codomain graph. If no initial match is found, return `None`. + const initial_match = new Match(this, other); + + const ___temp = (func: (ray: Graph) => Ray) => { + ([func(this), func(other)] as Ray).zip(([initial, terminal]) => { + if (!initial_match.try_add_vertex(initial, terminal)) + return None; //TODO, DOESNT ACTUALLY RETURN THE FUNCTION HERE. Wait till matcher is abstracted to fix this + }); + } + + ___temp(ray => ray.inputs); + ___temp(ray => ray.outputs); // TODO: See again, the same pattern over and over again, same on both sides. + + // If an initial match is found, try to find a total and surjective match of the domain graph into the codomain graph. + + return new Matches(this, other, initial_match, false) + .filter(match => match.is_surjective()); // TODO; With this filter it should allow you to keep looking + + // TODO::: Automatic?? + // If a total surjective match is not found, return `None`. + return None; + } } export class Chyp extends Ray { @@ -937,6 +977,13 @@ export class Chyp extends Ray { */ } + + /** + * Some more delegations here + */ + match_graph = (domain: Graph, codomain: Graph, convex: boolean = true): Matches => domain.match(codomain, convex); + match_rule = (rule: Rule, codomain: Graph, convex: boolean = true): Matches => rule.match(codomain, convex); + find_iso = (domain: Graph, codomain: Graph): Match => domain.find_iso(codomain); } export class CodeView extends Ray { @@ -1160,14 +1207,134 @@ export class Match extends Ray { return bool(True); } - try_add_edge = (domain_edge = int, codomain_edge = int): Ray => { throw new NotImplementedError(); } + /** + * Try to map `domain_edge` to `codomain_edge`. + * + * This must satisfy certain conditions, such as being injective and having consistency with the vertex map. + * + * @param domain_edge + * @param codomain_edge + * + * `True` if a consistent match is found mapping `domain_edge` to `codomain_edge`, otherwise `False`. + */ + try_add_edge = (initial: EData, terminal: EData): Ray => { + log(`Trying to add edge ${initial} -> ${terminal} to match:`); + log(this.toString()); + + // TODO: Again an equivalence + // Check the values of the domain and codomain edges match. + if (initial.value !== terminal.value) { + log(`Edge failed: values ${initial.value} != ${terminal.value}`) + return false; + } + + // The edge map must be injective. + if (this.edge_image.includes(terminal)) { + console.log('Edge failed: the map would become non-injective.'); + return false; + } + + // If the values match and the codomain edge has not already been mapped to, map domain edge to codomain edge. + this.edge_map[initial] = terminal; + this.edge_image.add(terminal); + + // Domain sources must match codomain sources and domain targets must match codomain targets. + + // TODO: Again more equivalences, just to log - debug mode + { + // initial = preimg + // terminal = image + + // Domain sources must match codomain sources and domain targets must match codomain targets. + if (initial.domain !== terminal.domain) { + log(`Edge domain ${initial.domain} does not match image domain ${terminal.domain}.`); + } + + // TODO, again both sides + if (initial.codomain !== terminal.codomain) { + log(`Edge codomain ${initial.codomain} does not match image codomain ${terminal.codomain}.`); + } + } + + // TODO: This too probably general pattern to extract + // Check a vertex map consistent with this edge pairing exists. + // TODO: + here is just concat, so that zip can easily match it + ([initial.source + initial.target, terminal.source + terminal.target] as Ray).zip(([initial_vertex, terminal_vertex]) => { + // Each vertex that is already mapped needs to be consistent. + // TODO: More equivlaency, could be on the vertecies themselves + if (this.vertex_map.includes(initial_vertex) && this.vertex_image[initial_vertex] !== terminal_vertex) { + log('Edge failed: inconsistent with previously mapped vertex.'); + return false; // TODO: NOT RETURNING AGAIN + } + + // Otherwise, a consistent match must be found vertex for unmapped source and target vertices. + + if (!this.try_add_vertex(initial_vertex, terminal_vertex)) { + log('Edge failed: couldn\'t add a source or target vertex.'); + return false; + } + }); + + log('Edge success.'); + return true; + } + + domain_neighbourhood_mapped = (vertex = int): Ray => { throw new NotImplementedError(); } map_scalars = (): Ray => { throw new NotImplementedError(); } more = (): Ray => { throw new NotImplementedError(); } - is_total = (): Ray => { throw new NotImplementedError(); } - is_surjective = (): Ray => { throw new NotImplementedError(); } - is_injective = (): Ray => { throw new NotImplementedError(); } - is_convex = (): Ray => { throw new NotImplementedError(); } + + + // TODO: Total=surjective on another level of description ??? + ___defuq = (string: 'image' | 'map', domain) => + this[`vertex_${string}`].count === domain.vertices.count + && this[`edge_${string}`].count === domain.edges.count; // TODO: Again vertex/edge pattern, just collapse to one check + + /** + * Return whether all domain vertices and edges have been mapped. + */ + is_total = (): Ray => this.___defuq('map', this.domain); + /** + * Return whether the vertex and edge maps are surjective. + */ + is_surjective = (): Ray => this.___defuq('image', this.codomain); + + /** + * Return whether the vertex and edge maps are injective. + */ + is_injective = (): Ray => { + // Since the edge map is always injective, we only need to check the vertex map is injective. TODO (GENERALIZE) + return this.vertex_map.count === this.vertex_image.count; + } + + /** + * Return whether this match is convex. + * + * A match is convex if: + * - It is injective. + * - Its image in the codomain hypergraph is a convex sub-hypergraph. This means that for any two nodes in the sub-hypergraph and any path between these two nodes, every hyperedge along the path is also in the sub-hypergraph. + * + * TODO: Just no overlap?? + */ + is_convex = (): Ray => { + if (!this.is_injective()) { //TODO: WHY? + return false; + } + + + // Check that the image sub-hypergraph is convex. Get all successors of vertices in the image of the output of the domain graph. + const output_image_successors = this.codomain.successors( + this.domain.outputs + .filter(vertex => this.vertex_map[vertex]) // TODO INCLUDES + ); // TODO, Why search in codomain fromi these, ?? this must be easier + + // Check there is no path from any vertices in the image of the domain outputs to a vertex in the image of the domain inputs. + this.domain.inputs + .filter(vertex => this.vertex_map.includes(vertex) && output_image_successors.includes(this.vertex_map[vertex])) + .any(() => { return false }) // TODO DOESNT ACTUALLY RETURNM + + return true; + } /** * TODO Not implemented;; @@ -1346,6 +1513,13 @@ export class Rule extends Ray { const result: Match = this.dpo(match).first().cast(); return result.codomain; } + + // TODO: Can probably just match Rule=Graph, and use only one of these methods?? + /** + * Return matches of the left side of `rule` into `graph`. + */ + match = (other: Graph, convex: boolean = true): Matches => new Matches(this.lhs, other, convex); + } export class RewriteState extends Ray { From 1a81cda56091757d488b30fd1a2453f8c66e09f1 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 15:12:13 +0100 Subject: [PATCH 038/138] 2024/02/10 - More naive translations --- src/@orbitmines/external/chyp/Chyp.ts | 130 +++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 3 deletions(-) diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index fc85408..b25daf4 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1279,11 +1279,135 @@ export class Match extends Ray { return true; } + /** + * Return whether all adjacent edges of a domain vertex are mapped. + */ + domain_neighbourhood_mapped = (vertex: VData): Ray => + ([vertex.in_edges + vertex.out_edges] as Ray).all(edge => this.edge_map.includes(edge)); + + /** + * # def cod_nhd_mapped(self, cod_v: int): + * # """Returns True if nhd(cod_v) is the range of emap""" + * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and + * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) + */ + + /** + * Try to extend the match by mapping all scalars (i.e. 0 -> 0 edges). + * + * Note that any matchings of scalars will yield isomorphic results under rewriting, so we don't return a list of all the possible matchings. + * + * Returns: `True` if all scalars in the domain are mapped injectively to scalars in the codomain, otherwise `False`. + */ + map_scalars = (): Ray => { + //TODO WHAT'S A SCALAR HERE? + // TODO: Again same pattern for (co)domain - flipped, two dimensional + const ___scalars = (domain: Graph, reverse: boolean) => { + const is = (ray: Ray) => reverse ? ray.count !== 0 : ray.count === 0; // TODO: Should be easier to just .not this + + return domain.edges + .filter((edge: EData) => this.is(edge.source) && this.is(edge.target)); + } + + const terminal = ___scalars(this.codomain, false); + const initial = ___scalars(this.domain, true); + + // Greedily try to map scalar edges in the domain to scalar edges in the codomain with the same value. + initial.all((initial_edge: EData) => { + // TODO: Put initial/terminal edge on a ray and then apply funcitons + + log(`Trying to map scalar edge ${initial_edge}`) + + let found_match = false; + + // TODO .enumerate?? + terminal.all(([i, terminal_edge]) => { + if (initial_edge.value !== terminal_edge.value) // ANother equiv + return; // TODO continue; + + // Map the domain scalar to the first codomain scalar available with the same value. + this.edge_map[initial_edge] = terminal_edge; + this.edge_image.add(terminal_edge); // TODO: Again map/image is just initial/terminal.. same as domain/codomain,, + + found_match = true; - domain_neighbourhood_mapped = (vertex = int): Ray => { throw new NotImplementedError(); } - map_scalars = (): Ray => { throw new NotImplementedError(); } - more = (): Ray => { throw new NotImplementedError(); } + // Since the edge map must be injective, if a scalar in the codomain is mapped to, remove it from the list of candidates for future domain scalars to be mapped to. + terminal.pop(i); // TODO: ??? + log(`Successfully mapped scalar ${initial_edge} -> ${terminal_edge}`) + + // TODO: BREAK ; any?? + }); + + if (!found_match) { + log(`Match failed: could not map scalar edge ${initial_edge}.`) + return false; // TODO DOESNT RETURN + } + }); + + return true; + } + + + // TODO: IF MORE JUST ADDS MORE MATCHES IN THIS DIRECTION, THAT SHOULD BE AUTOMATIC ON .match ... ? + /** + * Return any matches extending `self` by a single vertex or edge. + */ + more = (): Ray => { + // First, try to add an edge adjacent to any domain vertices that have already been matched. + this.vertex_map + // If all the edges adjacent to the current vertex have already been matched, continue. TODO: Could just be on the .vertex + .filter(initial_vertex => this.domain_neighbourhood_mapped(initial_vertex)) + .all((initial_vertex: VData) => { + // TODO: AS ZIp or something + const terminal_vertex = this.vertex_map[initial_vertex]; + + const ___test = (boundary: (ray: Graph) => Ray): Ray => { + // Try to extend the match by mapping an adjacent source edge. + boundary(this.domain) // TODO: AGAIN SAME THING + // If the edge has already been matched, continue. + .filter(edge => !this.edge_map.includes(edge)) + .all((initial_edge: EData) => { + + // Otherwise, try to map this edge into the codomain graph. + return boundary(this.codomain).map(terminal_edge => { + const potential_new_match = this.copy(); + + // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. + if (potential_new_match.try_add_edge(initial_edge, terminal_edge)) + return potential_new_match; + + return NONE;//todo + }); // TODO REMOVE NON-ADDED_ONES, doesnt actually reutn either + }) + + } + + ___test(ray => ray.in_edges); + ___test(ray => ray.out_edges); + + }); + + // If all domain edges adjacent to matched domain vertices have already been matched, try to match an unmatched domain vertex. + this.domain.vertices + // If the vertex has already been matched into the codomain graph, continue. (Note we have looked at the edge-neighbourhood of these vertices above) + .filter(initial_vertex => this.vertex_map.includes(initial_vertex)) // TODO: THIS THING IS JUST A COPY, AGAIN FROM THE VERTEX/EDGE DIFFERENTIATION FROM ABOVE + .all(initial_vertex => { + + // Try to map the current domain vertex to any of the codomain vertices, extending the current match with this map when successful. + return this.codomain.vertices.map((terminal_vertex: VData) => { + const potential_new_match = this.copy(); + + // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. + if (potential_new_match.try_add_vertex(initial_edge, terminal_edge)) + return potential_new_match; + + return NONE;//todo + }); // TODO: AGAIN DOESNT RETURN + }) + + return []; + } // TODO: Total=surjective on another level of description ??? ___defuq = (string: 'image' | 'map', domain) => From 290972873d976ebbcf611e1ed65174105f91b8a1 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 15:25:51 +0100 Subject: [PATCH 039/138] 2024/02/10 - More naive translations & setting up test suite --- src/@orbitmines/external/chyp/Chyp.spec.ts | 12 ++++ src/@orbitmines/external/chyp/Chyp.ts | 68 +++++++++++++++++++++- 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 src/@orbitmines/external/chyp/Chyp.spec.ts diff --git a/src/@orbitmines/external/chyp/Chyp.spec.ts b/src/@orbitmines/external/chyp/Chyp.spec.ts new file mode 100644 index 0000000..26b5fc0 --- /dev/null +++ b/src/@orbitmines/external/chyp/Chyp.spec.ts @@ -0,0 +1,12 @@ +import {Ray} from "../../explorer/Ray"; + +describe("Chyp", () => { + describe("Graph", () => { + test(".o", () => { + + expect('a').toBe('c'); + }) + + }); +}); + diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index b25daf4..76d66ab 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1469,10 +1469,74 @@ export class Match extends Ray { */ } +/** + * An iterator over matches of one graph into another. + * + * This class can be used to iterate over total matches of a graph into another, optionally requiring these matches to be convex. + * + * TODO: SUPPORT THIS/?::: + * A class instance works by keeping a stack of partial or total matches. + * When it is iterated over, it pops a match from its match stack if it is + * non-empty, otherwise the iteration is stopped. If a match has been popped, + * the instance returns the match if it is total (and convex if required). + * Otherwise, the instance tries to extend the match and add any extended + * matches to the stack, then continues this process of popping off the match + * stack and extending if possible until a valid match is found and returned. + */ export class Matches extends Ray { - __init__ = (domain = Graph, codomain = Graph): Ray => { throw new NotImplementedError(); } + __init__ = (domain = Graph, codomain = Graph): Ray => { + /** + * TODO + * if initial_match is None: + * initial_match = Match(domain=domain, codomain=codomain) + * self.convex = convex + * + * # Try to map scalars on the initial match. + * if initial_match.map_scalars(): + * self.match_stack = [initial_match] + * # If the scalars could not be mapped, set the match + * # stack to be empty. This means that not suitable matches + * # will be found by this class instance. + * else: + * self.match_stack = [] + */ + throw new NotImplementedError(); } __iter__ = (): Ray => { throw new NotImplementedError(); } - __next__ = (): Ray => { throw new NotImplementedError(); } + + /** + * Return the next suitable match found. + * + * A 'suitable' match is one that is total and, if `self.convex == True`, convex. + */ + __next__ = (): Ray => { + // TODO Like expected this, class can probably be dropped this just becomes + + return this.match_stack.dont_check_for_convex_or.is_convex; // TODO: Just generalize these on functions + + /** + * while len(self.match_stack) > 0: + * # Pop the match at the top of the match stack + * m = self.match_stack.pop() + * # If the match is total (and convex if required), return it. + * if m.is_total(): + * match_log("got successful match:\n" + str(m)) + * if self.convex: + * if m.is_convex(): + * match_log("match is convex, returning") + * return m + * else: + * match_log("match is not convex, dropping") + * else: + * return m + * # If the match at the top of the match stack was not total + * # (and convex if required), try to extend the match at the + * # top of the stack and add the results to the match stack. + * else: + * self.match_stack += m.more() + * # If a suitable match was not found, stop the iteration. + * raise StopIteration + */ + } } export class Rule extends Ray { From 192029b2873ac88dadb0d3e394a8c1e0a716c014 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 15:27:54 +0100 Subject: [PATCH 040/138] 2024/02/10 - Move to naive_pass file. - At least for the initial rewriting stuff --- src/@orbitmines/external/chyp/Chyp.ts | 1785 ----------------- src/@orbitmines/external/chyp/ChypCanvas.tsx | 10 +- .../external/chyp/Chyp_naive_pass.ts | 1785 +++++++++++++++++ src/profiles/FadiShawki/FadiShawki.ts | 2 +- useless_junk/generate_chyp.js | 2 +- 5 files changed, 1792 insertions(+), 1792 deletions(-) create mode 100644 src/@orbitmines/external/chyp/Chyp_naive_pass.ts diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index 76d66ab..e69de29 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1,1785 +0,0 @@ -import {JS, Ray} from "../../explorer/Ray"; -import {NotImplementedError} from "../../explorer/errors/errors"; - -/** - * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. - * GitHub: https://github.com/akissinger/chyp - * - * A simple way of phrasing this conversion, is that the concept of a 'Vertex', 'Edge', 'Graph', 'Rule', ..., 'Rewrite' are merged into one thing: a Ray. - * - * NOTE: - * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. - * - * - The .copy()'s are implemented on Ray. - * - * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. - * - * TODO: Probably want all these types at runtime, to display them - * - * TODO: Graph boundary is automatic with this structure? - * - * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? - * - * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. - * - * TODO: Can just move the terminal which holds the oointer to the boundary - * - * TODO: Automatically generate visual examples of all the methods - * - * TODO: Runtime errors as rays - * - * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph - */ -/** - * TODO: These coordinates used for inferences? - * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" - */ - -export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; - -export const Color = (t1: Ray = str('')): Ray => { throw new NotImplementedError() }; - -export class ValueError extends Error {} - -/** - * Non-default vertex types are identified by a string label - * - * str() | None() - No overloading in TypeScript ;( - */ -export const VType = JS.Iterable([str, None]); - -/** - * An error occurred in the graph backend. - * - * TODO probably hooked as a boolean, one successful the other not - */ -export class GraphError extends Error {} -export class RuleError extends Error {} - -/** - * Used for debugging (the matcher) - */ -const DEBUG = true; // TODO; Generalize -const log = (s: string) => { - if (!DEBUG) - return; - - console.log(s); -} - -/** - * Data associated with a single vertex. - */ -export class VData extends Ray { - // The vertex type. - vtype = this.property('vtype', None); - - // The register size (number of bundled parallel wires) of the vertex. - size = this.count; // Implemented on Ray.count - - // TODO: These infers will probably be removed? - // Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). - infer_type = this.property('infer_type', bool(False)) - // Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). - infer_size = this.property('infer_size', bool(False)) - - // x-coordinate at which to draw the vertex. - x = this.property('y', int(0)) - // y-coordinate at which to draw the vertex. - y = this.property('y', int(0)) - - highlight = this.property('highlight', bool(False)) - value = this.property('value') - - /** - * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. - * - * TODO ; // set[int] = set() - * TODO ; these are just the initial/terminal sides of a Ray. they're just duplicated - */ - get in_edges(): Ray { throw new NotImplementedError(); } - get out_edges(): Ray { throw new NotImplementedError(); } - - /** - * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. - */ - get in_indices(): Ray { return this.initial } // - get out_indices(): Ray { throw new NotImplementedError(); } - - is_input = (): Ray => this.in_indices.count.as_int() > 0; - is_output = (): Ray => this.out_indices.count.as_int() > 0; - is_boundary = (): Ray => this.is_input() || this.is_output(); - - // TODO: Probably generalizable - - /** - * - * @param other - */ - merge = (other: VData): Ray => { - // TODO: other is destroyed - // TODO: Vertices - // this.initial.equivalent(other.initial); - // this.terminal.equivalent(other.initial); - - /* - - vd = self.vertex_data(v) - # print("merging %s <- %s" % (v, w)) - - # Where vertex `w` occurs as an edge target, replace it with `v` - for e in self.in_edges(w): - ed = self.edge_data(e) - ed.t = [v if x == w else x for x in ed.t] - vd.in_edges.add(e) - - # Where vertex `w` occurs as an edge source, replace it with `v` - for e in self.out_edges(w): - ed = self.edge_data(e) - ed.s = [v if x == w else x for x in ed.s] - vd.out_edges.add(e) - - # Wherever `w` occurs on the graph boundary, replace it with `v` - self.set_inputs([v if x == w else x for x in self.inputs]) - self.set_outputs([v if x == w else x for x in self.outputs]) - - # Remove references to `w` from the graph - self.remove_vertex(w) - - */ - - throw new NotImplementedError(); - } - - fresh = (): VData => { - // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. - - // vtype=vd.vtype, size=vd.size, - // x=vd.x, y=vd.y, value=vd.value - - } - - // TODO: Shouldn't be here, this should be implemented on Ray if it's general enough - get domain(): Ray { return JS.Iterable([this.vtype, this.size]) }; - -} - -/** - * Data associated with a single edge. - */ -export class EData extends Ray { - - get source() { return this.s }; - get target() { return this.t }; - - // TODO: this is just the initial frame - get s(): Ray { throw new NotImplementedError(); } - // TODO: this is just the terminal frame - get t(): Ray { throw new NotImplementedError(); } - - fg = this.property('bg', Color()); - bg = this.property('bg', Color()); - x = this.property('y', int(0)); - // y-coordinate at which to draw the vertex. - y = this.property('y', int(0)); - highlight = this.property('highlight', bool(False)) - hyper = this.property('value', bool(True)) - value = this.property('value') - - __repr__ = (): Ray => { throw new NotImplementedError(); - // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' - } - - // TODO: More stuff to relate it to the screen that shouldnt be here. - /** - * Return how many width 'units' this box needs to display nicely. - * - * This uses a simple rule: - * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. - * - Otherwise draw as a larger (size 2) box. - */ - box_size = (): Ray => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); - - domain = (): Ray => this.source.cast().domain; - codomain = (): Ray => this.target.cast().domain; - - toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL -} - -/** - * A hypergraph with boundaries. - * - * This is the main data structure used by Chyp. It represents a directed - * hypergraph (which we call simply a "graph") as two dictionaries for - * vertices and (hyper)edges, respectively. Each vertex is associated with a - * `VData` object and edge edge with an `EData` object, which stores - * information about adjacency, position, label, etc. - * - * The particular flavor of hypergraphs we use associate to each hyperedge a - * list of source vertices and a list of target vertices. The hypergraph - * itself also has a list of input vertices and a list of output vertices, - * which are used for sequential composition and rewriting. - */ -export class Graph extends Ray { - - get vindex(): Ray { return this.vdata.index.max(0); } - get eindex(): Ray { return this.edata.index.max(0); } - - // Mapping from integer identifiers of each vertex to its data. - vdata = this.property('vertices'); - // Mapping from integer identifiers of each hyperedge to its data. - edata = this.property('edges'); - - // TODO .keys - vertices = this.property('vertices'); - edges = this.property('edges'); - - /** - * Return the domain of the graph. - * - * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. - */ - // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. - get domain(): Ray { return this.inputs.cast().domain; }; - - /** - * Return the domain of the graph. - * - * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. - */ - get codomain(): Ray { return this.outputs.cast().domain; }; - - vertex_data = (v = int): VData => this.vertices().at(v).cast(); - edge_data = (e = int): EData => this.edges().at(e).cast(); - - // TODO: Shouldnt be here - ___next_index = (name = int(-1), index: Ray): Ray => { - // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) - const current = name === -1 ? index : Math.max(name, index); - return current + 1; - } - - /** - * Add a new vertex to the graph. - * - * @param name The value carried by this vertex (currently unused). - * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. - * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). - */ - add_vertex = (name = int(-1), vertex: VData): VData => { - this.vindex = this.___next_index(name, this.vindex); - - this.vdata[this.vindex - 1] = vertex; - return vertex; - } - - /** - * Add a new hyperedge to the graph. - * - * @param s - * @param t - */ - add_edge = (name = int(-1), edge: EData): EData => { - this.eindex = this.___next_index(name, this.eindex); - - this.edata[this.eindex - 1] = edge; - - // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) - // for v in s: - // self.vdata[v].out_edges.add(e) - // for v in t: - // self.vdata[v].in_edges.add(e) - - return edge; - } - // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. - - /** - * Remove a vertex from the graph. - * - * This removes a single vertex. - * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. - * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. - * - * @param v - * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. - */ - remove_vertex = (v = int, strict: boolean = false): Ray => { - // TODO: destroy any reference of it (could just do this lazy) - // TODO: as delegation - - if (strict) { - if (this.vertex_data(v).in_edges.count.as_int() > 0 || this.vertex_data(v).out_edges > 0) { - throw new ValueError('Attempting to remove vertex with adjacent' - + 'edges while strict == True.'); - } - - if (this.inputs.includes(v) || this.outputs.includes(v)) { - throw new ValueError('Attempting to remove boundary vertex while' - + 'strict == True.'); - - }// TODO CAN BE SIMPLIFIED - } - - // in/out edges from all vertices - delete this.vdata[v]; - } - - /** - * Remove an edge from the graph. - * - * @param e Integer identifier of the edge to remove. - */ - remove_edge = (e = int): Ray => { - // TODO: destroy any reference of it (could just do this lazy) - // in/out edges from all vertices - delete this.edata[e]; - } - - // TODO: Can these be overlaoded in properties using -=, += in TS? - - /** - * Append `inp` to the inputs of the graph. - * - * @param inp The list of vertex integer identifiers of the appended inputs. - */ - add_inputs = (inp = list(int)): Ray => { - this.inputs.continues_with(inp); // TODO: Perhaps splat - } - /** - * Append `outp` to the outputs of the graph. - * - * @param outp The list of vertex integer identifiers of the appended outputs. - */ - add_outputs = (outp = list(int)): Ray => { - this.outputs.continues_with(outp); // TODO: Perhaps splat - } - // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) - - - // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. - - // Return the list of vertex ids of the graph inputs. - get inputs(): Ray { throw new NotImplementedError(); } - // Return the list of vertex ids of the graph outputs. - get outputs(): Ray { throw new NotImplementedError(); } - - // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs - set inputs(ray = list(int)) { throw new NotImplementedError(); } - set outputs(ray = list(int)) { throw new NotImplementedError(); } - - // TODO: Move these to a "reference-like" structure, need to be on VData.. - - /** - * These are all just slightly differently abstracted in TypeScript here to make them a little more native. - */ - set_inputs = (inp = list(int)): Ray => this.inputs = inp; - set_outputs = (outp = list(int)): Ray => this.outputs = outp; - - /** - * All these are just delegations from some Vertex/Edge structure. - */ - // .vertices - num_vertices = (): Ray => this.vertices().count.as_int(); - - // .edges - num_edges = (): Ray => this.edges().count.as_int(); - - // .vertex_data - is_input = (v = int): Ray => this.vertex_data(v).is_input(); - is_output = (v = int): Ray => this.vertex_data(v).is_output(); - is_boundary = (v = int): Ray => this.vertex_data(v).is_boundary(); - in_edges = (v = int): Ray => this.vertex_data(v).in_edges; - out_edges = (v = int): Ray => this.vertex_data(v).out_edges; - - // .edge_data - source = (e = int): Ray => this.edge_data(e).source; - target = (e = int): Ray => this.edge_data(e).target; - edge_domain = (edge_id = int): Ray => this.edge_data(edge_id).domain(); - edge_codomain = (edge_id = int): Ray => this.edge_data(edge_id).codomain(); - - /** - * Return vertices that lie on a directed path from any of `vs`. - * // TODO: Just traverse the rays, deduplicate using the index - */ - successors = (ray: Ray): Ray => ray.next; - - /** - * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. - * - * @param v Integer identifier of the vertex into which to merge `w`. - * @param w Integer identifier of the vertex to merge into `v`. - */ - merge_vertices = (v = int, w = int): Ray => this.vertex_data(v).merge(this.vertex_data(w)); - - /** - * Split a vertex into copies for each input, output, and tentacle. - * - * This is used for computing pushout complements of rules that aren't left-linear. - * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). - * - * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. - * - * @param v Integer identifier of vertex to be exploded. - */ - explode_vertex = (v = int): Ray => { - const vertex = this.vertex_data(v); - - // TODO; This just seems like another copy which minor changes - - const next_inputs = empty(); - const next_outputs = empty(); - - const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process - vertex: VData, - boundary: (vertex: VData) => Ray, - next_boundary: Ray - ) => { - // TODO: It's just a duplicated process for vertex/edge since their definition is separataed - - // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. - // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs]) - // TODO: Basically a copy, and replace this one vertex - - // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. - boundary(vertex).all(e => { - const edge: EData = e.cast(); - - edge.t = edge.t - .map(target => { - if (target === v) - return target; - - const fresh_vertex = vertex.fresh(); - next_boundary.add(this.add_vertex(fresh_vertex)) - boundary(fresh_vertex).add(edge); - }) - }); - - } - - // TODO: It's always just duplicated for both ends, - __temp(vertex, (vertex) => vertex.in_edges, next_inputs); - __temp(vertex, (vertex) => vertex.out_edges, next_outputs); - - // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. - vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal - vertex.out_edges.clear(); - - // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). - this.remove_vertex(vertex, true); - - return [next_inputs, next_outputs]; - } - - - /** - * Insert a new identity hyperedge after the given vertex. - * - * A new vertex is also created, which replaces the original vertex as the source of any edges in graph as well as any occurrences of the original vertex in the graph outputs. - * - * @param reverse - * - If `False`, the original vertex becomes the source of the ew identity hyperedge while the new vertex becomes the target. - * - If `True`, the source and target of the new identity are flipped. This can be used to break directed cycles, by neffectively introducing a cap and cup. - */ - insert_id_after = (v = int, reverse = bool(False)): Ray => { - const vertex = this.vertex_data(v); - - // Create a new vertex with the same vtype and size - // //TODO ; Which is this .fresh - const new_vertex = vertex.fresh(); - new_vertex.x += 3; - // The new vertex is highlighted whenever the orignal vertex is. - new_vertex.highlight = vertex.highlight; // TODO: This not done by .fresh? - - /** - * //TODO: BEcause it's inserted after, set the output (generalize to just moving the reference to the terminal. - * # Replace any occurences of the original vertex in the graph outputs - * # with the new vertex. - * self.set_outputs([x if x != v else w for x in self.outputs()]) - */ - - // Where the original vertex is the source of a hyperedge, replace it with the new vertex and register this change with the data instance of each vertex - // TODO syncs the out_edges fields, wd.out_edges.add(e) vd.out_edges.clear() - // TODO replace out_edges.source to new_vertex again - - // Assign the orignal and new vertex as source or target of the new identity edge, based on the `reverse` argument. - // TODO: Sets reverse just flipping around the initial/terminal.. - // TODO: s, t = ([v], [w]) if not reverse else ([w], [v]) - - // Create the new identity edge. - const edge = this.add_edge() // s, t, 'id', vd.x + 1.5, vd.y) - edge.hightlight = vertex.highlight; // The new edge is highlighted whenever the original vertex is. - - return edge; - } - - /** - * Take the monoidal product of this graph in-place with another. - * - * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. - * - * @param other - * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. - */ - tensor = (other: Graph, layout: boolean = true): Ray => { - - const a = this; - const b = other; - - const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] - - tensor.initial.any.y -= - tensor.initial.any.y.max(); // max_self - - tensor.terminal.any.y -= - (layout ? tensor.terminal.any.y.min() : 0) + 1; // min_other TODO: Why + 1 ? - - /** - * # self.set_inputs(self.inputs + [vmap[v] for v in other.inputs]) - * # self.set_outputs(self.outputs + [vmap[v] for v in other.outputs]) - * - * # Add the inputs and outputs of the other graph to this one. - * self.add_inputs([vmap[v] for v in other.inputs]) - * self.add_outputs([vmap[v] for v in other.outputs]) - */ - // TODO: Add equivalence/reference on the inputs/output extremes. - } - - /** - * Sequentially compose this graph in-place with another. - * - * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. - */ - compose = (other: Graph): Ray => { - // TODO Just matching outputs and inputs.. - - const a = this; - const b = other; - - // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" - const compose: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] - - // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. - - // TODO: This is just again an equivalence type check on the ends of the ray - - // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs - - { - if (compose.initial.count.as_int() !== compose.terminal.count.as_int()) - throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed - - /** - * for output_id, input_id in zip(self_outputs, other_inputs): - * output_data = self.vertex_data(output_id) - * input_data = other.vertex_data(input_id) - * if output_data.vtype != input_data.vtype: - * if not (output_data.infer_type or input_data.infer_type): - * raise GraphError( - * f'Codomain {self.codomain()} does not ' - * + f'match domain {other.domain()}' - * ) - * if output_data.size != input_data.size: - * if not (output_data.infer_size or input_data.infer_size): - * raise GraphError( - * f'Codomain {self.codomain()} does not ' - * + f'match domain {other.domain()}' - * ) - */ - } - - /** - * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. - */ - - // Compute the max x-coordinate of the edges and vertices in this graph. - - // TODO: Again, recursively going through everything defined on the initial side (outputs) - // Shift all vertices and edges of this graph below the x-axis. - compose.initial.any.x -= - compose.initial.any.x.max(); // max_self - - // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] - compose.terminal.any.x -= - compose.terminal.any.x.min(); // min_other - - // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. - /** - * plug1 = self.outputs - * plug2 = [vmap[v] for v in other.inputs] - * - * if len(plug1) != len(plug2): - * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' - * + f'outputs into one with {len(plug2)} inputs') - * - * self.set_outputs([vmap[v] for v in other.outputs]) - */ - - // [outputs to inputs] - // Go through pairs of vertices from each plug - compose.zip().all(([input, output]) => { - /** - * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. - */ - - // TODO: does this ever happen??? - // while p1 in quotient: - // p1 = quotient[p1] - // while p2 in quotient: - // p2 = quotient[p2] - - - // TODO, Again the same equivalence check for loops etc.. - { - // If the resulting p1 and p2 are not the same vertex, merge them. - if (input === output) - return; - - // TODO; DO this on the vertices; - // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) - - // If both vertices have flexible types that are not equal, raise an error due to ambiguity. - // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. - - - // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. - - ['vtype', 'size'].forEach(structure => { - const infer = `infer_${structure}`; - - if (input[infer] && output[infer] && input[structure] !== output[structure]) { - throw GraphError(`Ambiguous vertex ${structure} during composition.`) - - } else if (input[infer]) { - // Otherwise, if one vertex has a flexible type, ensure the vertex types match. - // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it - // TODO: Again both sides same thing.. - input[structure] = output[structure]; // TODO: Generalized structure - input[infer] = false; - } else if (output.infer_type) { - output[structure] = input[structure]; - output[infer] = false; - } - }); - - input.merge(output); - // # Register than p2 has been merged into p1. - // quotient[p2] = p1 - } - }); - } - - /** - * Return the tensor product of this graph with another. - * - * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them - */ - __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); - - /** - * Return the composition of the current graph with `other`. - * - * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. - * @param other - */ - __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); - - /** - * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer - */ - ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { - const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. - something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? - return a_copy; // Could generalize to either end - } - - /** - * Set the `highlight` flag for a set of vertices and edges. - * - * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. - * - * @param vertices A set of vertices to highlight. - * @param edges A set of edges to highlight. - */ - highlight = (vertices = set(int), edges = set(int)): Ray => { - // TODO Again, these could be merged - this.vdata - .filter(vertex => vertices.includes(vertex)) - .all(vertex => vertex.cast().highlight = bool(true)); - this.edata - .filter(edge => edges.includes(edge)) - .all(edge => edge.cast().highlight = bool(true)); - - - } - - /** - * Clear the `highlight` flag for all vertices/edges. - * - * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. - */ - unhighlight = (): Ray => { - // TODO: These could be merged - this.vdata.highlight = false; - this.edata.highlight = false; - } - - /** - * Return matches of domain into codomain. - */ - match = (other: Graph, convex: boolean = true): Matches => new Matches(this, other, convex); - - /** - * Return an isomorphism between graphs g and h if found, otherwise `None`. - * - * If found, the isomorphism is returned as a :py:class:`Matches` instance, whose vertex and edge maps are bijections. - */ - find_iso = (other: Graph): Match => { // TODO | NONE - - // TODO: Again, more equivalence checks - // First, check the domains and codomains are equal between the two graphs. - if (this.domain !== other.domain || this.codomain !== other.codomain) - return None; //TODO - - // Try to find an initial match mapping one of the boundary vertices of the domain graph to the corresponding boundary vertex (the vertex in the same input/output location) of the codomain graph. If no initial match is found, return `None`. - const initial_match = new Match(this, other); - - const ___temp = (func: (ray: Graph) => Ray) => { - ([func(this), func(other)] as Ray).zip(([initial, terminal]) => { - if (!initial_match.try_add_vertex(initial, terminal)) - return None; //TODO, DOESNT ACTUALLY RETURN THE FUNCTION HERE. Wait till matcher is abstracted to fix this - }); - } - - ___temp(ray => ray.inputs); - ___temp(ray => ray.outputs); // TODO: See again, the same pattern over and over again, same on both sides. - - // If an initial match is found, try to find a total and surjective match of the domain graph into the codomain graph. - - return new Matches(this, other, initial_match, false) - .filter(match => match.is_surjective()); // TODO; With this filter it should allow you to keep looking - - // TODO::: Automatic?? - // If a total surjective match is not found, return `None`. - return None; - } -} - -export class Chyp extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - - /** - * Load a .chyp graph file from the given path. - */ - load_graph = (path = str) => { - // TODO: From localStorage for now? - // with open(path) as f: - // g = graph_from_json(f.read()) - } - - /** - * Return a graph corresponding to the identity map. - * - * This graph has a single vertex which is both an input and an output. - */ - identity = (vertex: VData): Graph => { - const graph = new Graph(); - - vertex.x = 0; // TODO automatic>? - vertex.y = 0; - graph.add_vertex(int(-1), vertex); - // TODO synce input/output automatically? - // g.set_inputs([v]) - // g.set_outputs([v]) - - return graph; - } - - - ___map_domain = (domain: Ray, _default: VData): Ray => { - return domain.map(([vtype, size], i) => { - const vertex: VData = _default.copy().cast(); - // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere - vertex.x = -1.5; - vertex.y = i - (i-1) / 2; - - return vertex; - }) - } - - /** - * Return a graph with one hyperedge and given domain and codomain. - * - * @param _default - * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. - * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. - */ - gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { - const graph = new Graph(); - - const inputs = this.___map_domain(domain, _default) - .map(vertex => graph.add_vertex(vertex)); - const outputs = this.___map_domain(codomain, _default) - .map(vertex => graph.add_vertex(vertex)); - - // TODO This is probably automatic at some point, remove - const edge = new EData(); - edge.s = inputs; - edge.t = outputs; - graph.add_edge(int(-1), edge); - // g.set_inputs(inputs) - // g.set_outputs(outputs) - - return graph; - } - - /** - * Return a graph corresponding to the given permutation. - * - * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. - * - * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. - * - * @param p A permutation given as an n-element list of integers from 0 to n-1. - * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. - */ - perm = (p = list(int), domain: Ray, _default: VData) => { - - const graph = new Graph(); - const num_wires = p.count.as_int(); - - if (num_wires !== domain.count.as_int()) - throw new GraphError(`Domain ${domain} does not match length of permutation.`) - - // TODO use ___map_domain - const inputs = domain.map(([vtype, size], i) => { - const vertex: VData = _default.copy().cast(); - // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere - vertex.x = 0; - vertex.y = i - (num_wires - 1) / 2; - - return vertex; - }) - .map(vertex => graph.add_vertex(vertex)); - // const outputs = num_wires.range(i => [inputs[p[i]]) - - // TODO Should be automatic - // g.set_inputs(inputs) - // g.set_outputs(outputs) - return graph; - } - - graph_from_json = (json_string = str): Graph => { - const json = JSON.parse(json_string().as_string()); // TODO - - const graph = new Graph(); - - // TODO: Don't do this so naively - // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), - // y=float(vd["y"] if "y" in vd else 0.0), - // value=vd["value"] if "value" in vd else "", - // name=int(v)) - // for e, ed in j["edges"].items(): - // g.add_edge(s=[int(v) for v in ed["s"]], - // t=[int(v) for v in ed["t"]], - // value=ed["value"] if "value" in ed else "", - // x=float(ed["x"]) if "x" in ed else 0.0, - // y=float(ed["y"]) if "y" in ed else 0.0, - // hyper=bool(ed["hyper"]) if "hyper" in ed else True, - // name=int(e)) - // - // g.set_inputs([int(v) for v in j["inputs"]]) - // g.set_outputs([int(v) for v in j["outputs"]]) - // json.vertices.forEach(((vertex, i) => graph.add_vertex( - // i, - // new VData() - // )); - - return graph; - } - - /** - * # def wide_id() -> Graph: - * # return gen("id", 1, 1) - * - * # def id_perm(p: List[int]) -> Graph: - * # g = Graph() - * # size = len(p) - * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] - * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] - * - * # for i in range(size): - * # y = i - (size-1)/2 - * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) - * - * # g.set_inputs(inputs) - * # g.set_outputs(outputs) - * - * # return g - */ - - /** - * Return a graph corresponding to a vertex size redistribution. - * - * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. - * - * More generally, a conversion can be done between different lists of sizes, for some vertex type. - * - * @param domain A list of pairs (vertex type, register size) corresponding to each input vertex. - * @param codomain A list of pairs (vertex type, register size) corresponding to each output vertex. - */ - redistributer = (domain = list, codomain = list) => { - /** - * vtypes = set(vtype for vtype, _ in domain) - * vtypes.update(vtype for vtype, _ in codomain) - * if len(vtypes) > 1: - * raise GraphError('Size conversion cannot mix vertex types.') - * - * # Raise error if size conservation is violated - * domain_size = sum(size for _, size in domain) - * codomain_size = sum(size for _, size in codomain) - * if domain_size != codomain_size: - * raise GraphError(f'Sum of domain sizes ({domain_size}) does not equal' - * + f'sum of codomain sizes ({codomain_size}).') - * - * return gen('_redistributer', domain, codomain) - */ - - } - - /** - * Some more delegations here - */ - match_graph = (domain: Graph, codomain: Graph, convex: boolean = true): Matches => domain.match(codomain, convex); - match_rule = (rule: Rule, codomain: Graph, convex: boolean = true): Matches => rule.match(codomain, convex); - find_iso = (domain: Graph, codomain: Graph): Match => domain.find_iso(codomain); -} - -export class CodeView extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - popup_visible = (): Ray => { throw new NotImplementedError(); } - set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } - ident_at_cursor = (): Ray => { throw new NotImplementedError(); } - insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } - keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } - set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } - add_line_below = (text = str): Ray => { throw new NotImplementedError(); } -} - -export class CodeCompletionModel extends Ray { - __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } - set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } - data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } - rowCount = (): Ray => { throw new NotImplementedError(); } -} - -export class ChypDocument extends Ray { - __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } - confirm_close = (): Ray => { throw new NotImplementedError(); } - add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } - open = (file_name = str): Ray => { throw new NotImplementedError(); } - save = (): Ray => { throw new NotImplementedError(); } - save_as = (): Ray => { throw new NotImplementedError(); } -} - -export class Editor extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - title = (): Ray => { throw new NotImplementedError(); } - reset_state = (): Ray => { throw new NotImplementedError(); } - invalidate_text = (): Ray => { throw new NotImplementedError(); } - next_part = (): Ray => { throw new NotImplementedError(); } - jump_to_error = (): Ray => { throw new NotImplementedError(); } - show_errors = (): Ray => { throw new NotImplementedError(); } - show_at_cursor = (): Ray => { throw new NotImplementedError(); } - next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } - repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } - update_state = (): Ray => { throw new NotImplementedError(); } - import_at_cursor = (): Ray => { throw new NotImplementedError(); } -} - -export class CheckThread extends Ray { - __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } - run = (): Ray => { throw new NotImplementedError(); } -} - -export class ErrorListModel extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } - data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } - headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } - index = (row = int, column = int): Ray => { throw new NotImplementedError(); } - columnCount = (): Ray => { throw new NotImplementedError(); } - rowCount = (): Ray => { throw new NotImplementedError(); } - parent = (): Ray => { throw new NotImplementedError(); } -} - -export class EItem extends Ray { - __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } - paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } -} - -export class VItem extends Ray { - __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } - refresh = (): Ray => { throw new NotImplementedError(); } -} - -export class TItem extends Ray { - __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } - refresh = (): Ray => { throw new NotImplementedError(); } -} - -export class GraphScene extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } - add_items = (): Ray => { throw new NotImplementedError(); } - mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } - mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } - mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } -} - -export class GraphView extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } -} - -export class ChypHighlighter extends Ray { - __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } - set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } - highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } -} - -export class MainWindow extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - remove_empty_editor = (): Ray => { throw new NotImplementedError(); } - update_file_name = (): Ray => { throw new NotImplementedError(); } - tab_changed = (i = int): Ray => { throw new NotImplementedError(); } - update_themes = (): Ray => { throw new NotImplementedError(); } - recent_files = (): Ray => { throw new NotImplementedError(); } - update_recent_files = (): Ray => { throw new NotImplementedError(); } - add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } - close_tab = (): Ray => { throw new NotImplementedError(); } - new = (): Ray => { throw new NotImplementedError(); } - open = (): Ray => { throw new NotImplementedError(); } - save = (): Ray => { throw new NotImplementedError(); } - save_as = (): Ray => { throw new NotImplementedError(); } - undo = (): Ray => { throw new NotImplementedError(); } - redo = (): Ray => { throw new NotImplementedError(); } - show_errors = (): Ray => { throw new NotImplementedError(); } - add_rewrite_step = (): Ray => { throw new NotImplementedError(); } - repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } - next_rewrite = (): Ray => { throw new NotImplementedError(); } - next_part = (): Ray => { throw new NotImplementedError(); } - previous_part = (): Ray => { throw new NotImplementedError(); } - next_tab = (): Ray => { throw new NotImplementedError(); } - previous_tab = (): Ray => { throw new NotImplementedError(); } - goto_import = (): Ray => { throw new NotImplementedError(); } - closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } - build_menu = (): Ray => { throw new NotImplementedError(); } -} - -// TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? -export class Match extends Ray { - - get domain(): Graph { throw new NotImplementedError(); } - get codomain(): Graph { throw new NotImplementedError(); } - get vertex_map(): Ray { throw new NotImplementedError(); } - get vertex_image(): Ray { throw new NotImplementedError(); } - get edge_map(): Ray { throw new NotImplementedError(); } - get edge_image(): Ray { throw new NotImplementedError(); } - - __init__ = (): Ray => { throw new NotImplementedError(); } - __str__ = (): Ray => { - // (f'\tVertex map: {str(self.vertex_map)}' - // + f'\n\tEdge map: {str(self.edge_map)}') - // TODO - throw new NotImplementedError(); } - - // Implemented on Ray - // TODO; doesnt copy the graphs at domain/codomain - // copy = (): Ray => { throw new NotImplementedError(); } - - /** - * Try to map `domain_vertex` to `codomain_vertex`. - * - * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. - * - * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. - */ - try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { - - // If the vertex is already mapped, only check the new mapping is consistent with the current match. - if (this.vertex_map.includes(domain_vertex)) { - log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) - return this.vertex_map[domain_vertex] === codomain_vertex; - } - - // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. - // TODO: This should all be redundant, probably removed ... - - // Ensure the mapping preserves vertex type. - if (domain_vertex.vtype !== codomain_vertex.vtype) { - log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); - - return bool(False); - } - - // Ensure the mapping preserves vertex size. - if (domain_vertex.size !== codomain_vertex.size) { - log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) - return bool(False); - } - - // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. - if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { - log('Vertex failed: codomain vertex is boundary but domain vertex is not.') - return bool(False); - } - - // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. - if (this.vertex_image.includes(codomain_vertex)) { - // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. - if (!domain_vertex.is_boundary()) { - log('Vertex failed: non-injective on interior vertex.') - return bool(False); - } - - // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. - if (this.vertex_image.any(([mapped_vertex, image_vertex]) => - image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! - )) { - log('Vertex failed: non-injective on interior vertex.') - return bool(False); - } - - return bool(False); - } - - // If a new and consistent map is found, add it to the vertex map of this match. - this.vertex_map[domain_vertex] = codomain_vertex - this.vertex_image.add(codomain_vertex) - - // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. - - if (!domain_vertex.is_boundary()) { - if (domain_vertex.in_edges.count.as_int() !== codomain_vertex.in_edges.count.as_int()) { - log('Vertex failed: in_edges cannot satisfy gluing conditions.') - return bool(False) - } - if (domain_vertex.out_edges.count.as_int() !== codomain_vertex.out_edges.count.as_int()) { - log('Vertex failed: in_edges cannot satisfy gluing conditions.') - return bool(False) - } - } - - // If a new consistent map is added that satisfies the gluing conditions, we are successful. - log('Vertex success.') - return bool(True); - } - - /** - * Try to map `domain_edge` to `codomain_edge`. - * - * This must satisfy certain conditions, such as being injective and having consistency with the vertex map. - * - * @param domain_edge - * @param codomain_edge - * - * `True` if a consistent match is found mapping `domain_edge` to `codomain_edge`, otherwise `False`. - */ - try_add_edge = (initial: EData, terminal: EData): Ray => { - log(`Trying to add edge ${initial} -> ${terminal} to match:`); - log(this.toString()); - - // TODO: Again an equivalence - // Check the values of the domain and codomain edges match. - if (initial.value !== terminal.value) { - log(`Edge failed: values ${initial.value} != ${terminal.value}`) - return false; - } - - // The edge map must be injective. - if (this.edge_image.includes(terminal)) { - console.log('Edge failed: the map would become non-injective.'); - return false; - } - - // If the values match and the codomain edge has not already been mapped to, map domain edge to codomain edge. - this.edge_map[initial] = terminal; - this.edge_image.add(terminal); - - // Domain sources must match codomain sources and domain targets must match codomain targets. - - // TODO: Again more equivalences, just to log - debug mode - { - // initial = preimg - // terminal = image - - // Domain sources must match codomain sources and domain targets must match codomain targets. - if (initial.domain !== terminal.domain) { - log(`Edge domain ${initial.domain} does not match image domain ${terminal.domain}.`); - } - - // TODO, again both sides - if (initial.codomain !== terminal.codomain) { - log(`Edge codomain ${initial.codomain} does not match image codomain ${terminal.codomain}.`); - } - } - - // TODO: This too probably general pattern to extract - // Check a vertex map consistent with this edge pairing exists. - // TODO: + here is just concat, so that zip can easily match it - ([initial.source + initial.target, terminal.source + terminal.target] as Ray).zip(([initial_vertex, terminal_vertex]) => { - // Each vertex that is already mapped needs to be consistent. - // TODO: More equivlaency, could be on the vertecies themselves - if (this.vertex_map.includes(initial_vertex) && this.vertex_image[initial_vertex] !== terminal_vertex) { - log('Edge failed: inconsistent with previously mapped vertex.'); - return false; // TODO: NOT RETURNING AGAIN - } - - // Otherwise, a consistent match must be found vertex for unmapped source and target vertices. - - if (!this.try_add_vertex(initial_vertex, terminal_vertex)) { - log('Edge failed: couldn\'t add a source or target vertex.'); - return false; - } - }); - - log('Edge success.'); - return true; - } - - /** - * Return whether all adjacent edges of a domain vertex are mapped. - */ - domain_neighbourhood_mapped = (vertex: VData): Ray => - ([vertex.in_edges + vertex.out_edges] as Ray).all(edge => this.edge_map.includes(edge)); - - /** - * # def cod_nhd_mapped(self, cod_v: int): - * # """Returns True if nhd(cod_v) is the range of emap""" - * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and - * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) - */ - - /** - * Try to extend the match by mapping all scalars (i.e. 0 -> 0 edges). - * - * Note that any matchings of scalars will yield isomorphic results under rewriting, so we don't return a list of all the possible matchings. - * - * Returns: `True` if all scalars in the domain are mapped injectively to scalars in the codomain, otherwise `False`. - */ - map_scalars = (): Ray => { - //TODO WHAT'S A SCALAR HERE? - // TODO: Again same pattern for (co)domain - flipped, two dimensional - const ___scalars = (domain: Graph, reverse: boolean) => { - const is = (ray: Ray) => reverse ? ray.count !== 0 : ray.count === 0; // TODO: Should be easier to just .not this - - return domain.edges - .filter((edge: EData) => this.is(edge.source) && this.is(edge.target)); - } - - const terminal = ___scalars(this.codomain, false); - const initial = ___scalars(this.domain, true); - - // Greedily try to map scalar edges in the domain to scalar edges in the codomain with the same value. - initial.all((initial_edge: EData) => { - // TODO: Put initial/terminal edge on a ray and then apply funcitons - - log(`Trying to map scalar edge ${initial_edge}`) - - let found_match = false; - - // TODO .enumerate?? - terminal.all(([i, terminal_edge]) => { - if (initial_edge.value !== terminal_edge.value) // ANother equiv - return; // TODO continue; - - // Map the domain scalar to the first codomain scalar available with the same value. - this.edge_map[initial_edge] = terminal_edge; - this.edge_image.add(terminal_edge); // TODO: Again map/image is just initial/terminal.. same as domain/codomain,, - - found_match = true; - - // Since the edge map must be injective, if a scalar in the codomain is mapped to, remove it from the list of candidates for future domain scalars to be mapped to. - terminal.pop(i); // TODO: ??? - - log(`Successfully mapped scalar ${initial_edge} -> ${terminal_edge}`) - - // TODO: BREAK ; any?? - }); - - if (!found_match) { - log(`Match failed: could not map scalar edge ${initial_edge}.`) - return false; // TODO DOESNT RETURN - } - }); - - return true; - } - - - // TODO: IF MORE JUST ADDS MORE MATCHES IN THIS DIRECTION, THAT SHOULD BE AUTOMATIC ON .match ... ? - /** - * Return any matches extending `self` by a single vertex or edge. - */ - more = (): Ray => { - // First, try to add an edge adjacent to any domain vertices that have already been matched. - this.vertex_map - // If all the edges adjacent to the current vertex have already been matched, continue. TODO: Could just be on the .vertex - .filter(initial_vertex => this.domain_neighbourhood_mapped(initial_vertex)) - .all((initial_vertex: VData) => { - // TODO: AS ZIp or something - const terminal_vertex = this.vertex_map[initial_vertex]; - - const ___test = (boundary: (ray: Graph) => Ray): Ray => { - // Try to extend the match by mapping an adjacent source edge. - boundary(this.domain) // TODO: AGAIN SAME THING - // If the edge has already been matched, continue. - .filter(edge => !this.edge_map.includes(edge)) - .all((initial_edge: EData) => { - - // Otherwise, try to map this edge into the codomain graph. - return boundary(this.codomain).map(terminal_edge => { - const potential_new_match = this.copy(); - - // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. - if (potential_new_match.try_add_edge(initial_edge, terminal_edge)) - return potential_new_match; - - return NONE;//todo - }); // TODO REMOVE NON-ADDED_ONES, doesnt actually reutn either - }) - - } - - ___test(ray => ray.in_edges); - ___test(ray => ray.out_edges); - - }); - - // If all domain edges adjacent to matched domain vertices have already been matched, try to match an unmatched domain vertex. - this.domain.vertices - // If the vertex has already been matched into the codomain graph, continue. (Note we have looked at the edge-neighbourhood of these vertices above) - .filter(initial_vertex => this.vertex_map.includes(initial_vertex)) // TODO: THIS THING IS JUST A COPY, AGAIN FROM THE VERTEX/EDGE DIFFERENTIATION FROM ABOVE - .all(initial_vertex => { - - // Try to map the current domain vertex to any of the codomain vertices, extending the current match with this map when successful. - return this.codomain.vertices.map((terminal_vertex: VData) => { - const potential_new_match = this.copy(); - - // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. - if (potential_new_match.try_add_vertex(initial_edge, terminal_edge)) - return potential_new_match; - - return NONE;//todo - }); // TODO: AGAIN DOESNT RETURN - }) - - return []; - } - - // TODO: Total=surjective on another level of description ??? - ___defuq = (string: 'image' | 'map', domain) => - this[`vertex_${string}`].count === domain.vertices.count - && this[`edge_${string}`].count === domain.edges.count; // TODO: Again vertex/edge pattern, just collapse to one check - - /** - * Return whether all domain vertices and edges have been mapped. - */ - is_total = (): Ray => this.___defuq('map', this.domain); - /** - * Return whether the vertex and edge maps are surjective. - */ - is_surjective = (): Ray => this.___defuq('image', this.codomain); - - /** - * Return whether the vertex and edge maps are injective. - */ - is_injective = (): Ray => { - // Since the edge map is always injective, we only need to check the vertex map is injective. TODO (GENERALIZE) - return this.vertex_map.count === this.vertex_image.count; - } - - /** - * Return whether this match is convex. - * - * A match is convex if: - * - It is injective. - * - Its image in the codomain hypergraph is a convex sub-hypergraph. This means that for any two nodes in the sub-hypergraph and any path between these two nodes, every hyperedge along the path is also in the sub-hypergraph. - * - * TODO: Just no overlap?? - */ - is_convex = (): Ray => { - if (!this.is_injective()) { //TODO: WHY? - return false; - } - - - // Check that the image sub-hypergraph is convex. Get all successors of vertices in the image of the output of the domain graph. - const output_image_successors = this.codomain.successors( - this.domain.outputs - .filter(vertex => this.vertex_map[vertex]) // TODO INCLUDES - ); // TODO, Why search in codomain fromi these, ?? this must be easier - - // Check there is no path from any vertices in the image of the domain outputs to a vertex in the image of the domain inputs. - this.domain.inputs - .filter(vertex => this.vertex_map.includes(vertex) && output_image_successors.includes(this.vertex_map[vertex])) - .any(() => { return false }) // TODO DOESNT ACTUALLY RETURNM - - return true; - } - - /** - * TODO Not implemented;; - * # def cod_nhd_mapped(self, cod_v: int): - * # """Returns True if nhd(cod_v) is the range of emap""" - * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and - * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) - */ -} - -/** - * An iterator over matches of one graph into another. - * - * This class can be used to iterate over total matches of a graph into another, optionally requiring these matches to be convex. - * - * TODO: SUPPORT THIS/?::: - * A class instance works by keeping a stack of partial or total matches. - * When it is iterated over, it pops a match from its match stack if it is - * non-empty, otherwise the iteration is stopped. If a match has been popped, - * the instance returns the match if it is total (and convex if required). - * Otherwise, the instance tries to extend the match and add any extended - * matches to the stack, then continues this process of popping off the match - * stack and extending if possible until a valid match is found and returned. - */ -export class Matches extends Ray { - __init__ = (domain = Graph, codomain = Graph): Ray => { - /** - * TODO - * if initial_match is None: - * initial_match = Match(domain=domain, codomain=codomain) - * self.convex = convex - * - * # Try to map scalars on the initial match. - * if initial_match.map_scalars(): - * self.match_stack = [initial_match] - * # If the scalars could not be mapped, set the match - * # stack to be empty. This means that not suitable matches - * # will be found by this class instance. - * else: - * self.match_stack = [] - */ - throw new NotImplementedError(); } - __iter__ = (): Ray => { throw new NotImplementedError(); } - - /** - * Return the next suitable match found. - * - * A 'suitable' match is one that is total and, if `self.convex == True`, convex. - */ - __next__ = (): Ray => { - // TODO Like expected this, class can probably be dropped this just becomes - - return this.match_stack.dont_check_for_convex_or.is_convex; // TODO: Just generalize these on functions - - /** - * while len(self.match_stack) > 0: - * # Pop the match at the top of the match stack - * m = self.match_stack.pop() - * # If the match is total (and convex if required), return it. - * if m.is_total(): - * match_log("got successful match:\n" + str(m)) - * if self.convex: - * if m.is_convex(): - * match_log("match is convex, returning") - * return m - * else: - * match_log("match is not convex, dropping") - * else: - * return m - * # If the match at the top of the match stack was not total - * # (and convex if required), try to extend the match at the - * # top of the stack and add the results to the match stack. - * else: - * self.match_stack += m.more() - * # If a suitable match was not found, stop the iteration. - * raise StopIteration - */ - } -} - -export class Rule extends Ray { - get lhs(): Graph { throw new NotImplementedError(); } - get rhs(): Graph { throw new NotImplementedError(); } - - /** - * TODO: Put the name on each side of the rule, not the '-' hacky thing - */ - get name(): Ray { throw new NotImplementedError(); } - get equiv(): Ray { throw new NotImplementedError(); } - - __init__ = (name = str(''), equiv = bool(True)): Ray => { - // TODO: Maybe just move exception to a method on this thing - - if (this.lhs.domain !== this.rhs.domain) // TODO: !== - throw new RuleError(`Inputs must match on LHS and RHS of rule (${this.rhs.domain} != ${this.lhs.domain})`); - - if (this.lhs.codomain !== this.rhs.codomain) - throw new RuleError(`Outputs must match on LHS and RHS of rule (${this.rhs.codomain} != ${this.lhs.codomain})`) - - - throw new NotImplementedError(); - - } - - copy = (): Ray => { throw new NotImplementedError(); } - - // TODO: Could put this on ray, generalize to swapping - converse = (): Rule => { - // TODO remove this hacky thing - just tries to us -a / a - const name = this.name.as_string().startsWith('-') ? this.name.substring(1) : `-${this.name}`; - - const converse: Rule = this.copy().cast(); // TODO equiv=True? - converse.name = name; - - // TODO: Wont work, we just should swap initial/terminal;\ - //swap?? or change direction.. - // const swap = converse.rhs; - // converse.rhs = converse.lhs; - // converse.lhs = swap; - return converse; - } - - /** - * Returns True if boundary on lhs embeds injectively - */ - is_left_linear = (): Ray => { - // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading - return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() - .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. - } - - /** - * Do double-pushout rewriting - * - * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. - * @param match - */ - dpo = (match: Match): Ray => { - // if (!this.is_left_linear()) - // throw new NotImplementedError("Only left linear rules are supported for now") - - const rewritten_graph: Graph = match.codomain.copy(); - - // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? - - // Computes the push complement ?? (just the thing we're replacing right?) - // TODO: Removes the match from the copy? - this.lhs.edges.all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); - - const inputs = []; - const outputs = []; - - this.lhs.vertices.all(rule_vertex => { - const match_vertex = match.vertex_map[rule_vertex]; - - if (!this.lhs.is_boundary(rule_vertex)) { - rewritten_graph.remove_vertex(match_vertex); - return; - } - - const rule_input = this.lhs.vertex_data(rule_vertex).in_indices; - const rule_output = this.lhs.vertex_data(rule_vertex).out_indices; - - if (rule_input.count.as_int() === 1 && rule_output === 1) { - const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); - - if (match_input.count.as_int() !== 1 && match_output.count.as_int() !== 1) - throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); - - inputs[rule_vertex] = match_input[0]; - outputs[rule_vertex] = match_output[0]; - } else if (rule_input.count.as_int() > 1 || rule_output.count.as_int() > 1) { - throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); - } - }) - - // Embed Rule.rhs into rewritten_graph - const replacement = new Match(this.rhs, rewritten_graph); - - // TODO: This is probably another of these geeneral patterns, same thing on either ends composed as a single ray., - const input = new Ray(); // [this.lhs.inputs, this.rhs.inputs] - - // first map the inputs, using the matching of the lhs - input.zip().all(([initial, terminal]) => { - match.vertex_map[terminal] = inputs.includes(initial) ? inputs[initial] : match.vertex_map[initial]; - }); - - const output = new Ray(); // [this.lhs.outputs, this.rhs.outputs] - - // next map the outputs. if the same vertex is an input and an output in r.rhs, then merge them in h. - output.zip().all(([initial, terminal]) => { - // TODO: Again, both ends are very similar, there should probably be a direct flip in these, small difference at the end - const temp = outputs.includes(initial) ? outputs[initial] : match.vertex_map[initial]; - - if (match.vertex_map.includes(terminal)) { - rewritten_graph.merge_vertices(match.vertex_map[terminal], temp) - } else { - match.vertex_map[terminal] = temp; - } - }); - - // then map the interior to new, fresh vertices - this.rhs.vertices - .filter(vertex => !vertex.is_boundary()) - .all((vertex: VData) => { - // TODO Again the fresh thing repeated here - just because it's moving between graphs - const new_vertex = rewritten_graph.add_vertex(vertex.fresh()); - - match.vertex_map[vertex] = new_vertex; - match.vertex_image.add(new_vertex); - }); - - // now add the edges from rhs to h and connect them using vmap1 - // TODO: Again this should be the same thing as the vertices - this.rhs.edges. - all((edge: EData) => { - const new_edge = rewritten_graph.add_edge(); - /** - * e1 = h.add_edge([m1.vertex_map[v] for v in ed.s], - * [m1.vertex_map[v] for v in ed.t], - * ed.value, ed.x, ed.y, ed.fg, ed.bg, ed.hyper) - */ - - match.edge_map[edge] = new_edge; - match.edge_image.add(new_edge); - }) - - return replacement; - } - - /** - * Apply the given rewrite r to at match m and return the first result - * - * This is a convience wrapper for `dpo` for when the extra rewrite data isn't needed. - */ - rewrite = (match: Match): Graph => { - // TODO: except StopIteration: - // raise RuntimeError("Rewrite has no valid context") - - const result: Match = this.dpo(match).first().cast(); - return result.codomain; - } - - // TODO: Can probably just match Rule=Graph, and use only one of these methods?? - /** - * Return matches of the left side of `rule` into `graph`. - */ - match = (other: Graph, convex: boolean = true): Matches => new Matches(this.lhs, other, convex); - -} - -export class RewriteState extends Ray { - __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } -} - -export class State extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } - part_at = (pos = int): Ray => { throw new NotImplementedError(); } - var = (items = List(Any)): Ray => { throw new NotImplementedError(); } - module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } - num = (items = List(Any)): Ray => { throw new NotImplementedError(); } - type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } - type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } - id = (items = list(Any)): Ray => { throw new NotImplementedError(); } - id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } - eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } - le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } - perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } - size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } - par = (items = List(Any)): Ray => { throw new NotImplementedError(); } - gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } - color = (items = List(Any)): Ray => { throw new NotImplementedError(); } - import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } - tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } - nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } -} - -export class Tactic extends Ray { - __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } - repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } - error = (message = str): Ray => { throw new NotImplementedError(); } - has_goal = (): Ray => { throw new NotImplementedError(); } - global_rules = (): Ray => { throw new NotImplementedError(); } - lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } - add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } - add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } - __lhs = (target = str): Ray => { throw new NotImplementedError(); } - __rhs = (target = str): Ray => { throw new NotImplementedError(); } - __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } - __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } - rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } - rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } - rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } - rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } - validate_goal = (): Ray => { throw new NotImplementedError(); } - lhs = (): Ray => { throw new NotImplementedError(); } - rhs = (): Ray => { throw new NotImplementedError(); } - lhs_size = (): Ray => { throw new NotImplementedError(); } - rhs_size = (): Ray => { throw new NotImplementedError(); } - highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } - highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } - __reset = (): Ray => { throw new NotImplementedError(); } - next_rhs = (current = str): Ray => { throw new NotImplementedError(); } - run_check = (): Ray => { throw new NotImplementedError(); } - name = (): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } - make_rhs = (): Ray => { throw new NotImplementedError(); } -} - -export class RuleTac extends Ray { - name = (): Ray => { throw new NotImplementedError(); } - make_rhs = (): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } -} - -export class SimpTac extends Ray { - name = (): Ray => { throw new NotImplementedError(); } - __prepare_rules = (): Ray => { throw new NotImplementedError(); } - make_rhs = (): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } -} - diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 1df9f94..9097b15 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -102,7 +102,7 @@ const Interface = () => { // }) ]); - // Chyp.any.selection = Chyp; + // Chyp_naieve_pass.any.selection = Chyp_naieve_pass; // selection.o({...selection.o, position: add(selection.any.position ?? [0, 0, 0], [0, i * 2, 0])}) @@ -128,7 +128,7 @@ const Interface = () => { } - + const DEBUG = true; const debug: DebugResult = {}; @@ -245,9 +245,9 @@ const Interface = () => { return <>
- {/**/} - {/**/} - {/**/} + {/**/} + {/**/} + {/**/} {/**/} diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts new file mode 100644 index 0000000..76d66ab --- /dev/null +++ b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts @@ -0,0 +1,1785 @@ +import {JS, Ray} from "../../explorer/Ray"; +import {NotImplementedError} from "../../explorer/errors/errors"; + +/** + * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. + * GitHub: https://github.com/akissinger/chyp + * + * A simple way of phrasing this conversion, is that the concept of a 'Vertex', 'Edge', 'Graph', 'Rule', ..., 'Rewrite' are merged into one thing: a Ray. + * + * NOTE: + * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. + * + * - The .copy()'s are implemented on Ray. + * + * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. + * + * TODO: Probably want all these types at runtime, to display them + * + * TODO: Graph boundary is automatic with this structure? + * + * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? + * + * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. + * + * TODO: Can just move the terminal which holds the oointer to the boundary + * + * TODO: Automatically generate visual examples of all the methods + * + * TODO: Runtime errors as rays + * + * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph + */ +/** + * TODO: These coordinates used for inferences? + * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" + */ + +export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; + +export const Color = (t1: Ray = str('')): Ray => { throw new NotImplementedError() }; + +export class ValueError extends Error {} + +/** + * Non-default vertex types are identified by a string label + * + * str() | None() - No overloading in TypeScript ;( + */ +export const VType = JS.Iterable([str, None]); + +/** + * An error occurred in the graph backend. + * + * TODO probably hooked as a boolean, one successful the other not + */ +export class GraphError extends Error {} +export class RuleError extends Error {} + +/** + * Used for debugging (the matcher) + */ +const DEBUG = true; // TODO; Generalize +const log = (s: string) => { + if (!DEBUG) + return; + + console.log(s); +} + +/** + * Data associated with a single vertex. + */ +export class VData extends Ray { + // The vertex type. + vtype = this.property('vtype', None); + + // The register size (number of bundled parallel wires) of the vertex. + size = this.count; // Implemented on Ray.count + + // TODO: These infers will probably be removed? + // Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). + infer_type = this.property('infer_type', bool(False)) + // Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). + infer_size = this.property('infer_size', bool(False)) + + // x-coordinate at which to draw the vertex. + x = this.property('y', int(0)) + // y-coordinate at which to draw the vertex. + y = this.property('y', int(0)) + + highlight = this.property('highlight', bool(False)) + value = this.property('value') + + /** + * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. + * + * TODO ; // set[int] = set() + * TODO ; these are just the initial/terminal sides of a Ray. they're just duplicated + */ + get in_edges(): Ray { throw new NotImplementedError(); } + get out_edges(): Ray { throw new NotImplementedError(); } + + /** + * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. + */ + get in_indices(): Ray { return this.initial } // + get out_indices(): Ray { throw new NotImplementedError(); } + + is_input = (): Ray => this.in_indices.count.as_int() > 0; + is_output = (): Ray => this.out_indices.count.as_int() > 0; + is_boundary = (): Ray => this.is_input() || this.is_output(); + + // TODO: Probably generalizable + + /** + * + * @param other + */ + merge = (other: VData): Ray => { + // TODO: other is destroyed + // TODO: Vertices + // this.initial.equivalent(other.initial); + // this.terminal.equivalent(other.initial); + + /* + + vd = self.vertex_data(v) + # print("merging %s <- %s" % (v, w)) + + # Where vertex `w` occurs as an edge target, replace it with `v` + for e in self.in_edges(w): + ed = self.edge_data(e) + ed.t = [v if x == w else x for x in ed.t] + vd.in_edges.add(e) + + # Where vertex `w` occurs as an edge source, replace it with `v` + for e in self.out_edges(w): + ed = self.edge_data(e) + ed.s = [v if x == w else x for x in ed.s] + vd.out_edges.add(e) + + # Wherever `w` occurs on the graph boundary, replace it with `v` + self.set_inputs([v if x == w else x for x in self.inputs]) + self.set_outputs([v if x == w else x for x in self.outputs]) + + # Remove references to `w` from the graph + self.remove_vertex(w) + + */ + + throw new NotImplementedError(); + } + + fresh = (): VData => { + // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. + + // vtype=vd.vtype, size=vd.size, + // x=vd.x, y=vd.y, value=vd.value + + } + + // TODO: Shouldn't be here, this should be implemented on Ray if it's general enough + get domain(): Ray { return JS.Iterable([this.vtype, this.size]) }; + +} + +/** + * Data associated with a single edge. + */ +export class EData extends Ray { + + get source() { return this.s }; + get target() { return this.t }; + + // TODO: this is just the initial frame + get s(): Ray { throw new NotImplementedError(); } + // TODO: this is just the terminal frame + get t(): Ray { throw new NotImplementedError(); } + + fg = this.property('bg', Color()); + bg = this.property('bg', Color()); + x = this.property('y', int(0)); + // y-coordinate at which to draw the vertex. + y = this.property('y', int(0)); + highlight = this.property('highlight', bool(False)) + hyper = this.property('value', bool(True)) + value = this.property('value') + + __repr__ = (): Ray => { throw new NotImplementedError(); + // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' + } + + // TODO: More stuff to relate it to the screen that shouldnt be here. + /** + * Return how many width 'units' this box needs to display nicely. + * + * This uses a simple rule: + * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. + * - Otherwise draw as a larger (size 2) box. + */ + box_size = (): Ray => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); + + domain = (): Ray => this.source.cast().domain; + codomain = (): Ray => this.target.cast().domain; + + toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL +} + +/** + * A hypergraph with boundaries. + * + * This is the main data structure used by Chyp. It represents a directed + * hypergraph (which we call simply a "graph") as two dictionaries for + * vertices and (hyper)edges, respectively. Each vertex is associated with a + * `VData` object and edge edge with an `EData` object, which stores + * information about adjacency, position, label, etc. + * + * The particular flavor of hypergraphs we use associate to each hyperedge a + * list of source vertices and a list of target vertices. The hypergraph + * itself also has a list of input vertices and a list of output vertices, + * which are used for sequential composition and rewriting. + */ +export class Graph extends Ray { + + get vindex(): Ray { return this.vdata.index.max(0); } + get eindex(): Ray { return this.edata.index.max(0); } + + // Mapping from integer identifiers of each vertex to its data. + vdata = this.property('vertices'); + // Mapping from integer identifiers of each hyperedge to its data. + edata = this.property('edges'); + + // TODO .keys + vertices = this.property('vertices'); + edges = this.property('edges'); + + /** + * Return the domain of the graph. + * + * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. + */ + // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. + get domain(): Ray { return this.inputs.cast().domain; }; + + /** + * Return the domain of the graph. + * + * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. + */ + get codomain(): Ray { return this.outputs.cast().domain; }; + + vertex_data = (v = int): VData => this.vertices().at(v).cast(); + edge_data = (e = int): EData => this.edges().at(e).cast(); + + // TODO: Shouldnt be here + ___next_index = (name = int(-1), index: Ray): Ray => { + // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) + const current = name === -1 ? index : Math.max(name, index); + return current + 1; + } + + /** + * Add a new vertex to the graph. + * + * @param name The value carried by this vertex (currently unused). + * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. + * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). + */ + add_vertex = (name = int(-1), vertex: VData): VData => { + this.vindex = this.___next_index(name, this.vindex); + + this.vdata[this.vindex - 1] = vertex; + return vertex; + } + + /** + * Add a new hyperedge to the graph. + * + * @param s + * @param t + */ + add_edge = (name = int(-1), edge: EData): EData => { + this.eindex = this.___next_index(name, this.eindex); + + this.edata[this.eindex - 1] = edge; + + // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) + // for v in s: + // self.vdata[v].out_edges.add(e) + // for v in t: + // self.vdata[v].in_edges.add(e) + + return edge; + } + // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. + + /** + * Remove a vertex from the graph. + * + * This removes a single vertex. + * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. + * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. + * + * @param v + * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. + */ + remove_vertex = (v = int, strict: boolean = false): Ray => { + // TODO: destroy any reference of it (could just do this lazy) + // TODO: as delegation + + if (strict) { + if (this.vertex_data(v).in_edges.count.as_int() > 0 || this.vertex_data(v).out_edges > 0) { + throw new ValueError('Attempting to remove vertex with adjacent' + + 'edges while strict == True.'); + } + + if (this.inputs.includes(v) || this.outputs.includes(v)) { + throw new ValueError('Attempting to remove boundary vertex while' + + 'strict == True.'); + + }// TODO CAN BE SIMPLIFIED + } + + // in/out edges from all vertices + delete this.vdata[v]; + } + + /** + * Remove an edge from the graph. + * + * @param e Integer identifier of the edge to remove. + */ + remove_edge = (e = int): Ray => { + // TODO: destroy any reference of it (could just do this lazy) + // in/out edges from all vertices + delete this.edata[e]; + } + + // TODO: Can these be overlaoded in properties using -=, += in TS? + + /** + * Append `inp` to the inputs of the graph. + * + * @param inp The list of vertex integer identifiers of the appended inputs. + */ + add_inputs = (inp = list(int)): Ray => { + this.inputs.continues_with(inp); // TODO: Perhaps splat + } + /** + * Append `outp` to the outputs of the graph. + * + * @param outp The list of vertex integer identifiers of the appended outputs. + */ + add_outputs = (outp = list(int)): Ray => { + this.outputs.continues_with(outp); // TODO: Perhaps splat + } + // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) + + + // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. + + // Return the list of vertex ids of the graph inputs. + get inputs(): Ray { throw new NotImplementedError(); } + // Return the list of vertex ids of the graph outputs. + get outputs(): Ray { throw new NotImplementedError(); } + + // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs + set inputs(ray = list(int)) { throw new NotImplementedError(); } + set outputs(ray = list(int)) { throw new NotImplementedError(); } + + // TODO: Move these to a "reference-like" structure, need to be on VData.. + + /** + * These are all just slightly differently abstracted in TypeScript here to make them a little more native. + */ + set_inputs = (inp = list(int)): Ray => this.inputs = inp; + set_outputs = (outp = list(int)): Ray => this.outputs = outp; + + /** + * All these are just delegations from some Vertex/Edge structure. + */ + // .vertices + num_vertices = (): Ray => this.vertices().count.as_int(); + + // .edges + num_edges = (): Ray => this.edges().count.as_int(); + + // .vertex_data + is_input = (v = int): Ray => this.vertex_data(v).is_input(); + is_output = (v = int): Ray => this.vertex_data(v).is_output(); + is_boundary = (v = int): Ray => this.vertex_data(v).is_boundary(); + in_edges = (v = int): Ray => this.vertex_data(v).in_edges; + out_edges = (v = int): Ray => this.vertex_data(v).out_edges; + + // .edge_data + source = (e = int): Ray => this.edge_data(e).source; + target = (e = int): Ray => this.edge_data(e).target; + edge_domain = (edge_id = int): Ray => this.edge_data(edge_id).domain(); + edge_codomain = (edge_id = int): Ray => this.edge_data(edge_id).codomain(); + + /** + * Return vertices that lie on a directed path from any of `vs`. + * // TODO: Just traverse the rays, deduplicate using the index + */ + successors = (ray: Ray): Ray => ray.next; + + /** + * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. + * + * @param v Integer identifier of the vertex into which to merge `w`. + * @param w Integer identifier of the vertex to merge into `v`. + */ + merge_vertices = (v = int, w = int): Ray => this.vertex_data(v).merge(this.vertex_data(w)); + + /** + * Split a vertex into copies for each input, output, and tentacle. + * + * This is used for computing pushout complements of rules that aren't left-linear. + * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). + * + * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. + * + * @param v Integer identifier of vertex to be exploded. + */ + explode_vertex = (v = int): Ray => { + const vertex = this.vertex_data(v); + + // TODO; This just seems like another copy which minor changes + + const next_inputs = empty(); + const next_outputs = empty(); + + const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process + vertex: VData, + boundary: (vertex: VData) => Ray, + next_boundary: Ray + ) => { + // TODO: It's just a duplicated process for vertex/edge since their definition is separataed + + // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. + // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs]) + // TODO: Basically a copy, and replace this one vertex + + // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. + boundary(vertex).all(e => { + const edge: EData = e.cast(); + + edge.t = edge.t + .map(target => { + if (target === v) + return target; + + const fresh_vertex = vertex.fresh(); + next_boundary.add(this.add_vertex(fresh_vertex)) + boundary(fresh_vertex).add(edge); + }) + }); + + } + + // TODO: It's always just duplicated for both ends, + __temp(vertex, (vertex) => vertex.in_edges, next_inputs); + __temp(vertex, (vertex) => vertex.out_edges, next_outputs); + + // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. + vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal + vertex.out_edges.clear(); + + // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). + this.remove_vertex(vertex, true); + + return [next_inputs, next_outputs]; + } + + + /** + * Insert a new identity hyperedge after the given vertex. + * + * A new vertex is also created, which replaces the original vertex as the source of any edges in graph as well as any occurrences of the original vertex in the graph outputs. + * + * @param reverse + * - If `False`, the original vertex becomes the source of the ew identity hyperedge while the new vertex becomes the target. + * - If `True`, the source and target of the new identity are flipped. This can be used to break directed cycles, by neffectively introducing a cap and cup. + */ + insert_id_after = (v = int, reverse = bool(False)): Ray => { + const vertex = this.vertex_data(v); + + // Create a new vertex with the same vtype and size + // //TODO ; Which is this .fresh + const new_vertex = vertex.fresh(); + new_vertex.x += 3; + // The new vertex is highlighted whenever the orignal vertex is. + new_vertex.highlight = vertex.highlight; // TODO: This not done by .fresh? + + /** + * //TODO: BEcause it's inserted after, set the output (generalize to just moving the reference to the terminal. + * # Replace any occurences of the original vertex in the graph outputs + * # with the new vertex. + * self.set_outputs([x if x != v else w for x in self.outputs()]) + */ + + // Where the original vertex is the source of a hyperedge, replace it with the new vertex and register this change with the data instance of each vertex + // TODO syncs the out_edges fields, wd.out_edges.add(e) vd.out_edges.clear() + // TODO replace out_edges.source to new_vertex again + + // Assign the orignal and new vertex as source or target of the new identity edge, based on the `reverse` argument. + // TODO: Sets reverse just flipping around the initial/terminal.. + // TODO: s, t = ([v], [w]) if not reverse else ([w], [v]) + + // Create the new identity edge. + const edge = this.add_edge() // s, t, 'id', vd.x + 1.5, vd.y) + edge.hightlight = vertex.highlight; // The new edge is highlighted whenever the original vertex is. + + return edge; + } + + /** + * Take the monoidal product of this graph in-place with another. + * + * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. + * + * @param other + * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. + */ + tensor = (other: Graph, layout: boolean = true): Ray => { + + const a = this; + const b = other; + + const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] + + tensor.initial.any.y -= + tensor.initial.any.y.max(); // max_self + + tensor.terminal.any.y -= + (layout ? tensor.terminal.any.y.min() : 0) + 1; // min_other TODO: Why + 1 ? + + /** + * # self.set_inputs(self.inputs + [vmap[v] for v in other.inputs]) + * # self.set_outputs(self.outputs + [vmap[v] for v in other.outputs]) + * + * # Add the inputs and outputs of the other graph to this one. + * self.add_inputs([vmap[v] for v in other.inputs]) + * self.add_outputs([vmap[v] for v in other.outputs]) + */ + // TODO: Add equivalence/reference on the inputs/output extremes. + } + + /** + * Sequentially compose this graph in-place with another. + * + * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. + */ + compose = (other: Graph): Ray => { + // TODO Just matching outputs and inputs.. + + const a = this; + const b = other; + + // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" + const compose: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] + + // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. + + // TODO: This is just again an equivalence type check on the ends of the ray + + // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs + + { + if (compose.initial.count.as_int() !== compose.terminal.count.as_int()) + throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed + + /** + * for output_id, input_id in zip(self_outputs, other_inputs): + * output_data = self.vertex_data(output_id) + * input_data = other.vertex_data(input_id) + * if output_data.vtype != input_data.vtype: + * if not (output_data.infer_type or input_data.infer_type): + * raise GraphError( + * f'Codomain {self.codomain()} does not ' + * + f'match domain {other.domain()}' + * ) + * if output_data.size != input_data.size: + * if not (output_data.infer_size or input_data.infer_size): + * raise GraphError( + * f'Codomain {self.codomain()} does not ' + * + f'match domain {other.domain()}' + * ) + */ + } + + /** + * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. + */ + + // Compute the max x-coordinate of the edges and vertices in this graph. + + // TODO: Again, recursively going through everything defined on the initial side (outputs) + // Shift all vertices and edges of this graph below the x-axis. + compose.initial.any.x -= + compose.initial.any.x.max(); // max_self + + // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] + compose.terminal.any.x -= + compose.terminal.any.x.min(); // min_other + + // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. + /** + * plug1 = self.outputs + * plug2 = [vmap[v] for v in other.inputs] + * + * if len(plug1) != len(plug2): + * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' + * + f'outputs into one with {len(plug2)} inputs') + * + * self.set_outputs([vmap[v] for v in other.outputs]) + */ + + // [outputs to inputs] + // Go through pairs of vertices from each plug + compose.zip().all(([input, output]) => { + /** + * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. + */ + + // TODO: does this ever happen??? + // while p1 in quotient: + // p1 = quotient[p1] + // while p2 in quotient: + // p2 = quotient[p2] + + + // TODO, Again the same equivalence check for loops etc.. + { + // If the resulting p1 and p2 are not the same vertex, merge them. + if (input === output) + return; + + // TODO; DO this on the vertices; + // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) + + // If both vertices have flexible types that are not equal, raise an error due to ambiguity. + // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. + + + // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. + + ['vtype', 'size'].forEach(structure => { + const infer = `infer_${structure}`; + + if (input[infer] && output[infer] && input[structure] !== output[structure]) { + throw GraphError(`Ambiguous vertex ${structure} during composition.`) + + } else if (input[infer]) { + // Otherwise, if one vertex has a flexible type, ensure the vertex types match. + // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it + // TODO: Again both sides same thing.. + input[structure] = output[structure]; // TODO: Generalized structure + input[infer] = false; + } else if (output.infer_type) { + output[structure] = input[structure]; + output[infer] = false; + } + }); + + input.merge(output); + // # Register than p2 has been merged into p1. + // quotient[p2] = p1 + } + }); + } + + /** + * Return the tensor product of this graph with another. + * + * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them + */ + __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); + + /** + * Return the composition of the current graph with `other`. + * + * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. + * @param other + */ + __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); + + /** + * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer + */ + ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { + const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. + something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? + return a_copy; // Could generalize to either end + } + + /** + * Set the `highlight` flag for a set of vertices and edges. + * + * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. + * + * @param vertices A set of vertices to highlight. + * @param edges A set of edges to highlight. + */ + highlight = (vertices = set(int), edges = set(int)): Ray => { + // TODO Again, these could be merged + this.vdata + .filter(vertex => vertices.includes(vertex)) + .all(vertex => vertex.cast().highlight = bool(true)); + this.edata + .filter(edge => edges.includes(edge)) + .all(edge => edge.cast().highlight = bool(true)); + + + } + + /** + * Clear the `highlight` flag for all vertices/edges. + * + * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. + */ + unhighlight = (): Ray => { + // TODO: These could be merged + this.vdata.highlight = false; + this.edata.highlight = false; + } + + /** + * Return matches of domain into codomain. + */ + match = (other: Graph, convex: boolean = true): Matches => new Matches(this, other, convex); + + /** + * Return an isomorphism between graphs g and h if found, otherwise `None`. + * + * If found, the isomorphism is returned as a :py:class:`Matches` instance, whose vertex and edge maps are bijections. + */ + find_iso = (other: Graph): Match => { // TODO | NONE + + // TODO: Again, more equivalence checks + // First, check the domains and codomains are equal between the two graphs. + if (this.domain !== other.domain || this.codomain !== other.codomain) + return None; //TODO + + // Try to find an initial match mapping one of the boundary vertices of the domain graph to the corresponding boundary vertex (the vertex in the same input/output location) of the codomain graph. If no initial match is found, return `None`. + const initial_match = new Match(this, other); + + const ___temp = (func: (ray: Graph) => Ray) => { + ([func(this), func(other)] as Ray).zip(([initial, terminal]) => { + if (!initial_match.try_add_vertex(initial, terminal)) + return None; //TODO, DOESNT ACTUALLY RETURN THE FUNCTION HERE. Wait till matcher is abstracted to fix this + }); + } + + ___temp(ray => ray.inputs); + ___temp(ray => ray.outputs); // TODO: See again, the same pattern over and over again, same on both sides. + + // If an initial match is found, try to find a total and surjective match of the domain graph into the codomain graph. + + return new Matches(this, other, initial_match, false) + .filter(match => match.is_surjective()); // TODO; With this filter it should allow you to keep looking + + // TODO::: Automatic?? + // If a total surjective match is not found, return `None`. + return None; + } +} + +export class Chyp extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + + /** + * Load a .chyp graph file from the given path. + */ + load_graph = (path = str) => { + // TODO: From localStorage for now? + // with open(path) as f: + // g = graph_from_json(f.read()) + } + + /** + * Return a graph corresponding to the identity map. + * + * This graph has a single vertex which is both an input and an output. + */ + identity = (vertex: VData): Graph => { + const graph = new Graph(); + + vertex.x = 0; // TODO automatic>? + vertex.y = 0; + graph.add_vertex(int(-1), vertex); + // TODO synce input/output automatically? + // g.set_inputs([v]) + // g.set_outputs([v]) + + return graph; + } + + + ___map_domain = (domain: Ray, _default: VData): Ray => { + return domain.map(([vtype, size], i) => { + const vertex: VData = _default.copy().cast(); + // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere + vertex.x = -1.5; + vertex.y = i - (i-1) / 2; + + return vertex; + }) + } + + /** + * Return a graph with one hyperedge and given domain and codomain. + * + * @param _default + * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. + * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. + */ + gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { + const graph = new Graph(); + + const inputs = this.___map_domain(domain, _default) + .map(vertex => graph.add_vertex(vertex)); + const outputs = this.___map_domain(codomain, _default) + .map(vertex => graph.add_vertex(vertex)); + + // TODO This is probably automatic at some point, remove + const edge = new EData(); + edge.s = inputs; + edge.t = outputs; + graph.add_edge(int(-1), edge); + // g.set_inputs(inputs) + // g.set_outputs(outputs) + + return graph; + } + + /** + * Return a graph corresponding to the given permutation. + * + * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. + * + * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. + * + * @param p A permutation given as an n-element list of integers from 0 to n-1. + * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. + */ + perm = (p = list(int), domain: Ray, _default: VData) => { + + const graph = new Graph(); + const num_wires = p.count.as_int(); + + if (num_wires !== domain.count.as_int()) + throw new GraphError(`Domain ${domain} does not match length of permutation.`) + + // TODO use ___map_domain + const inputs = domain.map(([vtype, size], i) => { + const vertex: VData = _default.copy().cast(); + // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere + vertex.x = 0; + vertex.y = i - (num_wires - 1) / 2; + + return vertex; + }) + .map(vertex => graph.add_vertex(vertex)); + // const outputs = num_wires.range(i => [inputs[p[i]]) + + // TODO Should be automatic + // g.set_inputs(inputs) + // g.set_outputs(outputs) + return graph; + } + + graph_from_json = (json_string = str): Graph => { + const json = JSON.parse(json_string().as_string()); // TODO + + const graph = new Graph(); + + // TODO: Don't do this so naively + // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), + // y=float(vd["y"] if "y" in vd else 0.0), + // value=vd["value"] if "value" in vd else "", + // name=int(v)) + // for e, ed in j["edges"].items(): + // g.add_edge(s=[int(v) for v in ed["s"]], + // t=[int(v) for v in ed["t"]], + // value=ed["value"] if "value" in ed else "", + // x=float(ed["x"]) if "x" in ed else 0.0, + // y=float(ed["y"]) if "y" in ed else 0.0, + // hyper=bool(ed["hyper"]) if "hyper" in ed else True, + // name=int(e)) + // + // g.set_inputs([int(v) for v in j["inputs"]]) + // g.set_outputs([int(v) for v in j["outputs"]]) + // json.vertices.forEach(((vertex, i) => graph.add_vertex( + // i, + // new VData() + // )); + + return graph; + } + + /** + * # def wide_id() -> Graph: + * # return gen("id", 1, 1) + * + * # def id_perm(p: List[int]) -> Graph: + * # g = Graph() + * # size = len(p) + * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] + * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] + * + * # for i in range(size): + * # y = i - (size-1)/2 + * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) + * + * # g.set_inputs(inputs) + * # g.set_outputs(outputs) + * + * # return g + */ + + /** + * Return a graph corresponding to a vertex size redistribution. + * + * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. + * + * More generally, a conversion can be done between different lists of sizes, for some vertex type. + * + * @param domain A list of pairs (vertex type, register size) corresponding to each input vertex. + * @param codomain A list of pairs (vertex type, register size) corresponding to each output vertex. + */ + redistributer = (domain = list, codomain = list) => { + /** + * vtypes = set(vtype for vtype, _ in domain) + * vtypes.update(vtype for vtype, _ in codomain) + * if len(vtypes) > 1: + * raise GraphError('Size conversion cannot mix vertex types.') + * + * # Raise error if size conservation is violated + * domain_size = sum(size for _, size in domain) + * codomain_size = sum(size for _, size in codomain) + * if domain_size != codomain_size: + * raise GraphError(f'Sum of domain sizes ({domain_size}) does not equal' + * + f'sum of codomain sizes ({codomain_size}).') + * + * return gen('_redistributer', domain, codomain) + */ + + } + + /** + * Some more delegations here + */ + match_graph = (domain: Graph, codomain: Graph, convex: boolean = true): Matches => domain.match(codomain, convex); + match_rule = (rule: Rule, codomain: Graph, convex: boolean = true): Matches => rule.match(codomain, convex); + find_iso = (domain: Graph, codomain: Graph): Match => domain.find_iso(codomain); +} + +export class CodeView extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + popup_visible = (): Ray => { throw new NotImplementedError(); } + set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } + ident_at_cursor = (): Ray => { throw new NotImplementedError(); } + insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } + keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } + set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } + add_line_below = (text = str): Ray => { throw new NotImplementedError(); } +} + +export class CodeCompletionModel extends Ray { + __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } + set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } + data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } + rowCount = (): Ray => { throw new NotImplementedError(); } +} + +export class ChypDocument extends Ray { + __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } + confirm_close = (): Ray => { throw new NotImplementedError(); } + add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } + open = (file_name = str): Ray => { throw new NotImplementedError(); } + save = (): Ray => { throw new NotImplementedError(); } + save_as = (): Ray => { throw new NotImplementedError(); } +} + +export class Editor extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + title = (): Ray => { throw new NotImplementedError(); } + reset_state = (): Ray => { throw new NotImplementedError(); } + invalidate_text = (): Ray => { throw new NotImplementedError(); } + next_part = (): Ray => { throw new NotImplementedError(); } + jump_to_error = (): Ray => { throw new NotImplementedError(); } + show_errors = (): Ray => { throw new NotImplementedError(); } + show_at_cursor = (): Ray => { throw new NotImplementedError(); } + next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } + repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } + update_state = (): Ray => { throw new NotImplementedError(); } + import_at_cursor = (): Ray => { throw new NotImplementedError(); } +} + +export class CheckThread extends Ray { + __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } + run = (): Ray => { throw new NotImplementedError(); } +} + +export class ErrorListModel extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } + data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } + headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } + index = (row = int, column = int): Ray => { throw new NotImplementedError(); } + columnCount = (): Ray => { throw new NotImplementedError(); } + rowCount = (): Ray => { throw new NotImplementedError(); } + parent = (): Ray => { throw new NotImplementedError(); } +} + +export class EItem extends Ray { + __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } + paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } +} + +export class VItem extends Ray { + __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } + refresh = (): Ray => { throw new NotImplementedError(); } +} + +export class TItem extends Ray { + __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } + refresh = (): Ray => { throw new NotImplementedError(); } +} + +export class GraphScene extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } + add_items = (): Ray => { throw new NotImplementedError(); } + mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } + mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } + mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } +} + +export class GraphView extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } +} + +export class ChypHighlighter extends Ray { + __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } + set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } + highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } +} + +export class MainWindow extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + remove_empty_editor = (): Ray => { throw new NotImplementedError(); } + update_file_name = (): Ray => { throw new NotImplementedError(); } + tab_changed = (i = int): Ray => { throw new NotImplementedError(); } + update_themes = (): Ray => { throw new NotImplementedError(); } + recent_files = (): Ray => { throw new NotImplementedError(); } + update_recent_files = (): Ray => { throw new NotImplementedError(); } + add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } + close_tab = (): Ray => { throw new NotImplementedError(); } + new = (): Ray => { throw new NotImplementedError(); } + open = (): Ray => { throw new NotImplementedError(); } + save = (): Ray => { throw new NotImplementedError(); } + save_as = (): Ray => { throw new NotImplementedError(); } + undo = (): Ray => { throw new NotImplementedError(); } + redo = (): Ray => { throw new NotImplementedError(); } + show_errors = (): Ray => { throw new NotImplementedError(); } + add_rewrite_step = (): Ray => { throw new NotImplementedError(); } + repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } + next_rewrite = (): Ray => { throw new NotImplementedError(); } + next_part = (): Ray => { throw new NotImplementedError(); } + previous_part = (): Ray => { throw new NotImplementedError(); } + next_tab = (): Ray => { throw new NotImplementedError(); } + previous_tab = (): Ray => { throw new NotImplementedError(); } + goto_import = (): Ray => { throw new NotImplementedError(); } + closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } + build_menu = (): Ray => { throw new NotImplementedError(); } +} + +// TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? +export class Match extends Ray { + + get domain(): Graph { throw new NotImplementedError(); } + get codomain(): Graph { throw new NotImplementedError(); } + get vertex_map(): Ray { throw new NotImplementedError(); } + get vertex_image(): Ray { throw new NotImplementedError(); } + get edge_map(): Ray { throw new NotImplementedError(); } + get edge_image(): Ray { throw new NotImplementedError(); } + + __init__ = (): Ray => { throw new NotImplementedError(); } + __str__ = (): Ray => { + // (f'\tVertex map: {str(self.vertex_map)}' + // + f'\n\tEdge map: {str(self.edge_map)}') + // TODO + throw new NotImplementedError(); } + + // Implemented on Ray + // TODO; doesnt copy the graphs at domain/codomain + // copy = (): Ray => { throw new NotImplementedError(); } + + /** + * Try to map `domain_vertex` to `codomain_vertex`. + * + * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. + * + * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. + */ + try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { + + // If the vertex is already mapped, only check the new mapping is consistent with the current match. + if (this.vertex_map.includes(domain_vertex)) { + log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) + return this.vertex_map[domain_vertex] === codomain_vertex; + } + + // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. + // TODO: This should all be redundant, probably removed ... + + // Ensure the mapping preserves vertex type. + if (domain_vertex.vtype !== codomain_vertex.vtype) { + log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); + + return bool(False); + } + + // Ensure the mapping preserves vertex size. + if (domain_vertex.size !== codomain_vertex.size) { + log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) + return bool(False); + } + + // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. + if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { + log('Vertex failed: codomain vertex is boundary but domain vertex is not.') + return bool(False); + } + + // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. + if (this.vertex_image.includes(codomain_vertex)) { + // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. + if (!domain_vertex.is_boundary()) { + log('Vertex failed: non-injective on interior vertex.') + return bool(False); + } + + // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. + if (this.vertex_image.any(([mapped_vertex, image_vertex]) => + image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! + )) { + log('Vertex failed: non-injective on interior vertex.') + return bool(False); + } + + return bool(False); + } + + // If a new and consistent map is found, add it to the vertex map of this match. + this.vertex_map[domain_vertex] = codomain_vertex + this.vertex_image.add(codomain_vertex) + + // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. + + if (!domain_vertex.is_boundary()) { + if (domain_vertex.in_edges.count.as_int() !== codomain_vertex.in_edges.count.as_int()) { + log('Vertex failed: in_edges cannot satisfy gluing conditions.') + return bool(False) + } + if (domain_vertex.out_edges.count.as_int() !== codomain_vertex.out_edges.count.as_int()) { + log('Vertex failed: in_edges cannot satisfy gluing conditions.') + return bool(False) + } + } + + // If a new consistent map is added that satisfies the gluing conditions, we are successful. + log('Vertex success.') + return bool(True); + } + + /** + * Try to map `domain_edge` to `codomain_edge`. + * + * This must satisfy certain conditions, such as being injective and having consistency with the vertex map. + * + * @param domain_edge + * @param codomain_edge + * + * `True` if a consistent match is found mapping `domain_edge` to `codomain_edge`, otherwise `False`. + */ + try_add_edge = (initial: EData, terminal: EData): Ray => { + log(`Trying to add edge ${initial} -> ${terminal} to match:`); + log(this.toString()); + + // TODO: Again an equivalence + // Check the values of the domain and codomain edges match. + if (initial.value !== terminal.value) { + log(`Edge failed: values ${initial.value} != ${terminal.value}`) + return false; + } + + // The edge map must be injective. + if (this.edge_image.includes(terminal)) { + console.log('Edge failed: the map would become non-injective.'); + return false; + } + + // If the values match and the codomain edge has not already been mapped to, map domain edge to codomain edge. + this.edge_map[initial] = terminal; + this.edge_image.add(terminal); + + // Domain sources must match codomain sources and domain targets must match codomain targets. + + // TODO: Again more equivalences, just to log - debug mode + { + // initial = preimg + // terminal = image + + // Domain sources must match codomain sources and domain targets must match codomain targets. + if (initial.domain !== terminal.domain) { + log(`Edge domain ${initial.domain} does not match image domain ${terminal.domain}.`); + } + + // TODO, again both sides + if (initial.codomain !== terminal.codomain) { + log(`Edge codomain ${initial.codomain} does not match image codomain ${terminal.codomain}.`); + } + } + + // TODO: This too probably general pattern to extract + // Check a vertex map consistent with this edge pairing exists. + // TODO: + here is just concat, so that zip can easily match it + ([initial.source + initial.target, terminal.source + terminal.target] as Ray).zip(([initial_vertex, terminal_vertex]) => { + // Each vertex that is already mapped needs to be consistent. + // TODO: More equivlaency, could be on the vertecies themselves + if (this.vertex_map.includes(initial_vertex) && this.vertex_image[initial_vertex] !== terminal_vertex) { + log('Edge failed: inconsistent with previously mapped vertex.'); + return false; // TODO: NOT RETURNING AGAIN + } + + // Otherwise, a consistent match must be found vertex for unmapped source and target vertices. + + if (!this.try_add_vertex(initial_vertex, terminal_vertex)) { + log('Edge failed: couldn\'t add a source or target vertex.'); + return false; + } + }); + + log('Edge success.'); + return true; + } + + /** + * Return whether all adjacent edges of a domain vertex are mapped. + */ + domain_neighbourhood_mapped = (vertex: VData): Ray => + ([vertex.in_edges + vertex.out_edges] as Ray).all(edge => this.edge_map.includes(edge)); + + /** + * # def cod_nhd_mapped(self, cod_v: int): + * # """Returns True if nhd(cod_v) is the range of emap""" + * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and + * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) + */ + + /** + * Try to extend the match by mapping all scalars (i.e. 0 -> 0 edges). + * + * Note that any matchings of scalars will yield isomorphic results under rewriting, so we don't return a list of all the possible matchings. + * + * Returns: `True` if all scalars in the domain are mapped injectively to scalars in the codomain, otherwise `False`. + */ + map_scalars = (): Ray => { + //TODO WHAT'S A SCALAR HERE? + // TODO: Again same pattern for (co)domain - flipped, two dimensional + const ___scalars = (domain: Graph, reverse: boolean) => { + const is = (ray: Ray) => reverse ? ray.count !== 0 : ray.count === 0; // TODO: Should be easier to just .not this + + return domain.edges + .filter((edge: EData) => this.is(edge.source) && this.is(edge.target)); + } + + const terminal = ___scalars(this.codomain, false); + const initial = ___scalars(this.domain, true); + + // Greedily try to map scalar edges in the domain to scalar edges in the codomain with the same value. + initial.all((initial_edge: EData) => { + // TODO: Put initial/terminal edge on a ray and then apply funcitons + + log(`Trying to map scalar edge ${initial_edge}`) + + let found_match = false; + + // TODO .enumerate?? + terminal.all(([i, terminal_edge]) => { + if (initial_edge.value !== terminal_edge.value) // ANother equiv + return; // TODO continue; + + // Map the domain scalar to the first codomain scalar available with the same value. + this.edge_map[initial_edge] = terminal_edge; + this.edge_image.add(terminal_edge); // TODO: Again map/image is just initial/terminal.. same as domain/codomain,, + + found_match = true; + + // Since the edge map must be injective, if a scalar in the codomain is mapped to, remove it from the list of candidates for future domain scalars to be mapped to. + terminal.pop(i); // TODO: ??? + + log(`Successfully mapped scalar ${initial_edge} -> ${terminal_edge}`) + + // TODO: BREAK ; any?? + }); + + if (!found_match) { + log(`Match failed: could not map scalar edge ${initial_edge}.`) + return false; // TODO DOESNT RETURN + } + }); + + return true; + } + + + // TODO: IF MORE JUST ADDS MORE MATCHES IN THIS DIRECTION, THAT SHOULD BE AUTOMATIC ON .match ... ? + /** + * Return any matches extending `self` by a single vertex or edge. + */ + more = (): Ray => { + // First, try to add an edge adjacent to any domain vertices that have already been matched. + this.vertex_map + // If all the edges adjacent to the current vertex have already been matched, continue. TODO: Could just be on the .vertex + .filter(initial_vertex => this.domain_neighbourhood_mapped(initial_vertex)) + .all((initial_vertex: VData) => { + // TODO: AS ZIp or something + const terminal_vertex = this.vertex_map[initial_vertex]; + + const ___test = (boundary: (ray: Graph) => Ray): Ray => { + // Try to extend the match by mapping an adjacent source edge. + boundary(this.domain) // TODO: AGAIN SAME THING + // If the edge has already been matched, continue. + .filter(edge => !this.edge_map.includes(edge)) + .all((initial_edge: EData) => { + + // Otherwise, try to map this edge into the codomain graph. + return boundary(this.codomain).map(terminal_edge => { + const potential_new_match = this.copy(); + + // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. + if (potential_new_match.try_add_edge(initial_edge, terminal_edge)) + return potential_new_match; + + return NONE;//todo + }); // TODO REMOVE NON-ADDED_ONES, doesnt actually reutn either + }) + + } + + ___test(ray => ray.in_edges); + ___test(ray => ray.out_edges); + + }); + + // If all domain edges adjacent to matched domain vertices have already been matched, try to match an unmatched domain vertex. + this.domain.vertices + // If the vertex has already been matched into the codomain graph, continue. (Note we have looked at the edge-neighbourhood of these vertices above) + .filter(initial_vertex => this.vertex_map.includes(initial_vertex)) // TODO: THIS THING IS JUST A COPY, AGAIN FROM THE VERTEX/EDGE DIFFERENTIATION FROM ABOVE + .all(initial_vertex => { + + // Try to map the current domain vertex to any of the codomain vertices, extending the current match with this map when successful. + return this.codomain.vertices.map((terminal_vertex: VData) => { + const potential_new_match = this.copy(); + + // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. + if (potential_new_match.try_add_vertex(initial_edge, terminal_edge)) + return potential_new_match; + + return NONE;//todo + }); // TODO: AGAIN DOESNT RETURN + }) + + return []; + } + + // TODO: Total=surjective on another level of description ??? + ___defuq = (string: 'image' | 'map', domain) => + this[`vertex_${string}`].count === domain.vertices.count + && this[`edge_${string}`].count === domain.edges.count; // TODO: Again vertex/edge pattern, just collapse to one check + + /** + * Return whether all domain vertices and edges have been mapped. + */ + is_total = (): Ray => this.___defuq('map', this.domain); + /** + * Return whether the vertex and edge maps are surjective. + */ + is_surjective = (): Ray => this.___defuq('image', this.codomain); + + /** + * Return whether the vertex and edge maps are injective. + */ + is_injective = (): Ray => { + // Since the edge map is always injective, we only need to check the vertex map is injective. TODO (GENERALIZE) + return this.vertex_map.count === this.vertex_image.count; + } + + /** + * Return whether this match is convex. + * + * A match is convex if: + * - It is injective. + * - Its image in the codomain hypergraph is a convex sub-hypergraph. This means that for any two nodes in the sub-hypergraph and any path between these two nodes, every hyperedge along the path is also in the sub-hypergraph. + * + * TODO: Just no overlap?? + */ + is_convex = (): Ray => { + if (!this.is_injective()) { //TODO: WHY? + return false; + } + + + // Check that the image sub-hypergraph is convex. Get all successors of vertices in the image of the output of the domain graph. + const output_image_successors = this.codomain.successors( + this.domain.outputs + .filter(vertex => this.vertex_map[vertex]) // TODO INCLUDES + ); // TODO, Why search in codomain fromi these, ?? this must be easier + + // Check there is no path from any vertices in the image of the domain outputs to a vertex in the image of the domain inputs. + this.domain.inputs + .filter(vertex => this.vertex_map.includes(vertex) && output_image_successors.includes(this.vertex_map[vertex])) + .any(() => { return false }) // TODO DOESNT ACTUALLY RETURNM + + return true; + } + + /** + * TODO Not implemented;; + * # def cod_nhd_mapped(self, cod_v: int): + * # """Returns True if nhd(cod_v) is the range of emap""" + * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and + * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) + */ +} + +/** + * An iterator over matches of one graph into another. + * + * This class can be used to iterate over total matches of a graph into another, optionally requiring these matches to be convex. + * + * TODO: SUPPORT THIS/?::: + * A class instance works by keeping a stack of partial or total matches. + * When it is iterated over, it pops a match from its match stack if it is + * non-empty, otherwise the iteration is stopped. If a match has been popped, + * the instance returns the match if it is total (and convex if required). + * Otherwise, the instance tries to extend the match and add any extended + * matches to the stack, then continues this process of popping off the match + * stack and extending if possible until a valid match is found and returned. + */ +export class Matches extends Ray { + __init__ = (domain = Graph, codomain = Graph): Ray => { + /** + * TODO + * if initial_match is None: + * initial_match = Match(domain=domain, codomain=codomain) + * self.convex = convex + * + * # Try to map scalars on the initial match. + * if initial_match.map_scalars(): + * self.match_stack = [initial_match] + * # If the scalars could not be mapped, set the match + * # stack to be empty. This means that not suitable matches + * # will be found by this class instance. + * else: + * self.match_stack = [] + */ + throw new NotImplementedError(); } + __iter__ = (): Ray => { throw new NotImplementedError(); } + + /** + * Return the next suitable match found. + * + * A 'suitable' match is one that is total and, if `self.convex == True`, convex. + */ + __next__ = (): Ray => { + // TODO Like expected this, class can probably be dropped this just becomes + + return this.match_stack.dont_check_for_convex_or.is_convex; // TODO: Just generalize these on functions + + /** + * while len(self.match_stack) > 0: + * # Pop the match at the top of the match stack + * m = self.match_stack.pop() + * # If the match is total (and convex if required), return it. + * if m.is_total(): + * match_log("got successful match:\n" + str(m)) + * if self.convex: + * if m.is_convex(): + * match_log("match is convex, returning") + * return m + * else: + * match_log("match is not convex, dropping") + * else: + * return m + * # If the match at the top of the match stack was not total + * # (and convex if required), try to extend the match at the + * # top of the stack and add the results to the match stack. + * else: + * self.match_stack += m.more() + * # If a suitable match was not found, stop the iteration. + * raise StopIteration + */ + } +} + +export class Rule extends Ray { + get lhs(): Graph { throw new NotImplementedError(); } + get rhs(): Graph { throw new NotImplementedError(); } + + /** + * TODO: Put the name on each side of the rule, not the '-' hacky thing + */ + get name(): Ray { throw new NotImplementedError(); } + get equiv(): Ray { throw new NotImplementedError(); } + + __init__ = (name = str(''), equiv = bool(True)): Ray => { + // TODO: Maybe just move exception to a method on this thing + + if (this.lhs.domain !== this.rhs.domain) // TODO: !== + throw new RuleError(`Inputs must match on LHS and RHS of rule (${this.rhs.domain} != ${this.lhs.domain})`); + + if (this.lhs.codomain !== this.rhs.codomain) + throw new RuleError(`Outputs must match on LHS and RHS of rule (${this.rhs.codomain} != ${this.lhs.codomain})`) + + + throw new NotImplementedError(); + + } + + copy = (): Ray => { throw new NotImplementedError(); } + + // TODO: Could put this on ray, generalize to swapping + converse = (): Rule => { + // TODO remove this hacky thing - just tries to us -a / a + const name = this.name.as_string().startsWith('-') ? this.name.substring(1) : `-${this.name}`; + + const converse: Rule = this.copy().cast(); // TODO equiv=True? + converse.name = name; + + // TODO: Wont work, we just should swap initial/terminal;\ + //swap?? or change direction.. + // const swap = converse.rhs; + // converse.rhs = converse.lhs; + // converse.lhs = swap; + return converse; + } + + /** + * Returns True if boundary on lhs embeds injectively + */ + is_left_linear = (): Ray => { + // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading + return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() + .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. + } + + /** + * Do double-pushout rewriting + * + * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. + * @param match + */ + dpo = (match: Match): Ray => { + // if (!this.is_left_linear()) + // throw new NotImplementedError("Only left linear rules are supported for now") + + const rewritten_graph: Graph = match.codomain.copy(); + + // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? + + // Computes the push complement ?? (just the thing we're replacing right?) + // TODO: Removes the match from the copy? + this.lhs.edges.all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); + + const inputs = []; + const outputs = []; + + this.lhs.vertices.all(rule_vertex => { + const match_vertex = match.vertex_map[rule_vertex]; + + if (!this.lhs.is_boundary(rule_vertex)) { + rewritten_graph.remove_vertex(match_vertex); + return; + } + + const rule_input = this.lhs.vertex_data(rule_vertex).in_indices; + const rule_output = this.lhs.vertex_data(rule_vertex).out_indices; + + if (rule_input.count.as_int() === 1 && rule_output === 1) { + const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); + + if (match_input.count.as_int() !== 1 && match_output.count.as_int() !== 1) + throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); + + inputs[rule_vertex] = match_input[0]; + outputs[rule_vertex] = match_output[0]; + } else if (rule_input.count.as_int() > 1 || rule_output.count.as_int() > 1) { + throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); + } + }) + + // Embed Rule.rhs into rewritten_graph + const replacement = new Match(this.rhs, rewritten_graph); + + // TODO: This is probably another of these geeneral patterns, same thing on either ends composed as a single ray., + const input = new Ray(); // [this.lhs.inputs, this.rhs.inputs] + + // first map the inputs, using the matching of the lhs + input.zip().all(([initial, terminal]) => { + match.vertex_map[terminal] = inputs.includes(initial) ? inputs[initial] : match.vertex_map[initial]; + }); + + const output = new Ray(); // [this.lhs.outputs, this.rhs.outputs] + + // next map the outputs. if the same vertex is an input and an output in r.rhs, then merge them in h. + output.zip().all(([initial, terminal]) => { + // TODO: Again, both ends are very similar, there should probably be a direct flip in these, small difference at the end + const temp = outputs.includes(initial) ? outputs[initial] : match.vertex_map[initial]; + + if (match.vertex_map.includes(terminal)) { + rewritten_graph.merge_vertices(match.vertex_map[terminal], temp) + } else { + match.vertex_map[terminal] = temp; + } + }); + + // then map the interior to new, fresh vertices + this.rhs.vertices + .filter(vertex => !vertex.is_boundary()) + .all((vertex: VData) => { + // TODO Again the fresh thing repeated here - just because it's moving between graphs + const new_vertex = rewritten_graph.add_vertex(vertex.fresh()); + + match.vertex_map[vertex] = new_vertex; + match.vertex_image.add(new_vertex); + }); + + // now add the edges from rhs to h and connect them using vmap1 + // TODO: Again this should be the same thing as the vertices + this.rhs.edges. + all((edge: EData) => { + const new_edge = rewritten_graph.add_edge(); + /** + * e1 = h.add_edge([m1.vertex_map[v] for v in ed.s], + * [m1.vertex_map[v] for v in ed.t], + * ed.value, ed.x, ed.y, ed.fg, ed.bg, ed.hyper) + */ + + match.edge_map[edge] = new_edge; + match.edge_image.add(new_edge); + }) + + return replacement; + } + + /** + * Apply the given rewrite r to at match m and return the first result + * + * This is a convience wrapper for `dpo` for when the extra rewrite data isn't needed. + */ + rewrite = (match: Match): Graph => { + // TODO: except StopIteration: + // raise RuntimeError("Rewrite has no valid context") + + const result: Match = this.dpo(match).first().cast(); + return result.codomain; + } + + // TODO: Can probably just match Rule=Graph, and use only one of these methods?? + /** + * Return matches of the left side of `rule` into `graph`. + */ + match = (other: Graph, convex: boolean = true): Matches => new Matches(this.lhs, other, convex); + +} + +export class RewriteState extends Ray { + __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } +} + +export class State extends Ray { + __init__ = (): Ray => { throw new NotImplementedError(); } + part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } + part_at = (pos = int): Ray => { throw new NotImplementedError(); } + var = (items = List(Any)): Ray => { throw new NotImplementedError(); } + module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } + num = (items = List(Any)): Ray => { throw new NotImplementedError(); } + type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } + type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } + id = (items = list(Any)): Ray => { throw new NotImplementedError(); } + id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } + eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } + le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } + perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } + size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } + par = (items = List(Any)): Ray => { throw new NotImplementedError(); } + gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } + color = (items = List(Any)): Ray => { throw new NotImplementedError(); } + import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } + tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } + nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } +} + +export class Tactic extends Ray { + __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } + repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } + error = (message = str): Ray => { throw new NotImplementedError(); } + has_goal = (): Ray => { throw new NotImplementedError(); } + global_rules = (): Ray => { throw new NotImplementedError(); } + lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } + add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } + add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } + __lhs = (target = str): Ray => { throw new NotImplementedError(); } + __rhs = (target = str): Ray => { throw new NotImplementedError(); } + __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } + __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } + rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } + rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } + rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } + rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } + validate_goal = (): Ray => { throw new NotImplementedError(); } + lhs = (): Ray => { throw new NotImplementedError(); } + rhs = (): Ray => { throw new NotImplementedError(); } + lhs_size = (): Ray => { throw new NotImplementedError(); } + rhs_size = (): Ray => { throw new NotImplementedError(); } + highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } + highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } + __reset = (): Ray => { throw new NotImplementedError(); } + next_rhs = (current = str): Ray => { throw new NotImplementedError(); } + run_check = (): Ray => { throw new NotImplementedError(); } + name = (): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } + make_rhs = (): Ray => { throw new NotImplementedError(); } +} + +export class RuleTac extends Ray { + name = (): Ray => { throw new NotImplementedError(); } + make_rhs = (): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } +} + +export class SimpTac extends Ray { + name = (): Ray => { throw new NotImplementedError(); } + __prepare_rules = (): Ray => { throw new NotImplementedError(); } + make_rhs = (): Ray => { throw new NotImplementedError(); } + check = (): Ray => { throw new NotImplementedError(); } +} + diff --git a/src/profiles/FadiShawki/FadiShawki.ts b/src/profiles/FadiShawki/FadiShawki.ts index 62feb91..d403ff6 100644 --- a/src/profiles/FadiShawki/FadiShawki.ts +++ b/src/profiles/FadiShawki/FadiShawki.ts @@ -14,7 +14,7 @@ const REFERENCES = { }, CHYP_COMPOSING_HYPERGRAPHS_PROVING_THEOREMS: { reference: { - title: 'Chyp: Composing Hypergraphs, Proving Theorems', + title: 'Chyp_naieve_pass: Composing Hypergraphs, Proving Theorems', authors: [{name: 'Aleks Kissinger'}], organizations: [], year: '(2023)', diff --git a/useless_junk/generate_chyp.js b/useless_junk/generate_chyp.js index bdebe1d..d99736b 100644 --- a/useless_junk/generate_chyp.js +++ b/useless_junk/generate_chyp.js @@ -127,4 +127,4 @@ ${generateTypeScriptTypes(classesAndMethods)} `; -fs.writeFileSync('../src/@orbitmines/external/implementations/chyp/Chyp.ts', typeScriptCode) \ No newline at end of file +fs.writeFileSync('../src/@orbitmines/external/implementations/chyp/Chyp_naieve_pass.ts', typeScriptCode) \ No newline at end of file From 28cee3dfe9dbd429ea762dd5aad34d10b7bbfbeb Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 16:02:19 +0100 Subject: [PATCH 041/138] 2024/02/10 - Some project logistics for README.md --- README.md | 27 +++++++++++++++++++------ src/@orbitmines/README.md | 24 ---------------------- src/@orbitmines/external/chyp/Chyp.ts | 11 ++++++++++ src/@orbitmines/external/chyp/README.md | 9 +++++++++ 4 files changed, 41 insertions(+), 30 deletions(-) delete mode 100644 src/@orbitmines/README.md create mode 100644 src/@orbitmines/external/chyp/README.md diff --git a/README.md b/README.md index f0a49ec..46f544e 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,30 @@ --- -#### Discussion +**What is this?, What is OrbitMines?, What are Rays?** -Feel free to discuss this project on this GitHub repository or preferably the [OrbitMines Community Discord](https://discord.orbitmines.com). +A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hyper-/)'Edge', (hyper-/)'Graph', (hyper-/)'Rule', (hyper-/)'Tactic', (hyper-/)..., (hyper-/)'Rewrite' are merged into one thing: a [Ray](https://github.com/orbitmines/orbitmines.com/blob/main/src/%40orbitmines/explorer/Ray.ts). It handles surrounding context, ignorances, equivalences, ..., differentiation. (And if it cannot, then it offers a way of implementing it for all of the above) + +- If you prefer **text**, see [2023-12-31. On Orbits, Equivalence and Inconsistencies](https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies), or more generally my/OrbitMines writing can be found here: [orbitmines.com/profiles/fadi-shawki](https://orbitmines.com/profiles/fadi-shawki). + + +- If you prefer **audio-visual mumblings**, see [2024-01-04. What is OrbitMines?, Implementing Aleks Kissinger's Chyp and maybe looking at Tinygrad](https://www.youtube.com/watch?v=O6v_gzlI1kY), or more generally my streams can be found here: [youtube.com/@FadiShawki/streams](https://www.youtube.com/@FadiShawki/streams). + + +- If you prefer **archaic symbolics: i.e. code**, see [Ray.ts](https://github.com/orbitmines/orbitmines.com/blob/main/src/%40orbitmines/explorer/Ray.ts) (or locally: [local/Ray.ts](./src/@orbitmines/explorer/Ray.ts)), or more generally my/OrbitMines code can be found here [github.com/orbitmines](https://github.com/orbitmines/). + + +- If you prefer discussions on **Discord**: [discord.orbitmines.com](https://discord.orbitmines.com). + + +- Or if prefer smashing your keyboard till there's something interesting on the screen. See a first implementation of this *explorational interface*: [orbitmines.com/explorer/github.com/akissinger/chyp](https://orbitmines.com/explorer/github.com/akissinger/chyp). --- -#### Latest Writing - Some context on this project +### Some general notes about this project -[2023-12-31. On Orbits, Equivalence and Inconsistencies](http://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies/ -) -![on-orbits-equivalence-and-inconsistencies](public/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/3840x2160.jpeg) +> [!IMPORTANT] +> Anything in this directory should be considered as deprecated. It is merely used as the initial (crude) bootstrap for OrbitMines. And will surely be replaced at some point - it is not (yet) meant as a formal spec. +> [!WARNING] +> No proper security audit has yet been done on its current iteration. diff --git a/src/@orbitmines/README.md b/src/@orbitmines/README.md deleted file mode 100644 index 51c6d99..0000000 --- a/src/@orbitmines/README.md +++ /dev/null @@ -1,24 +0,0 @@ -![orbitmines.logo.3000x1000.png](..%2Flib%2Forganizations%2Forbitmines%2Flogo%2Forbitmines.logo.3000x1000.png) - -# OrbitMines -*An explorational interface.* - ---- - -> [!IMPORTANT] -> Anything in this directory should be considered as deprecated. It is merely used as the initial (crude) bootstrap for OrbitMines. And will surely be replaced at some point - it is not meant as a formal spec. - ---- - -## Contributing & Discussion - -Feel free to discuss this project on this GitHub repository or preferably the [OrbitMines Community Discord](https://discord.orbitmines.com). - ---- - -## Security - -> [!WARNING] -> No proper security audit has yet been done on its current iteration (TODO: link to thread for contributions & discussions). - ---- \ No newline at end of file diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index e69de29..ebfc02b 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -0,0 +1,11 @@ +/** + * An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Rays. + * + * **What is this?, What are Rays?** + * + * See the `README.md` at [github.com/orbitmines/orbitmines.com](https://github.com/orbitmines/orbitmines.com). Or locally: [README.md](../../../../README.md) + * + * **Why is this interface here?** + * + * Note that this is mainly here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. Or considered as a legacy translation, which will be accessibly through OrbitMines. + */ \ No newline at end of file diff --git a/src/@orbitmines/external/chyp/README.md b/src/@orbitmines/external/chyp/README.md new file mode 100644 index 0000000..ddcfbd3 --- /dev/null +++ b/src/@orbitmines/external/chyp/README.md @@ -0,0 +1,9 @@ +An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Rays. + +**What is this?, What are Rays?** + +See the `README.md` at [github.com/orbitmines/orbitmines.com](https://github.com/orbitmines/orbitmines.com). Or locally: [README.md](../../../../README.md) + +**Why is this interface here?** + +Note that this is mainly here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. Or considered as a legacy translation, which will be accessibly through OrbitMines. \ No newline at end of file From f9b48c6529163c83c9d83836b796546fcca00710 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 16:04:54 +0100 Subject: [PATCH 042/138] 2024/02/10 - Some project logistics for README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 46f544e..6a027a3 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ --- -**What is this?, What is OrbitMines?, What are Rays?** +## What is this?, What is OrbitMines?, What are Rays? A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hyper-/)'Edge', (hyper-/)'Graph', (hyper-/)'Rule', (hyper-/)'Tactic', (hyper-/)..., (hyper-/)'Rewrite' are merged into one thing: a [Ray](https://github.com/orbitmines/orbitmines.com/blob/main/src/%40orbitmines/explorer/Ray.ts). It handles surrounding context, ignorances, equivalences, ..., differentiation. (And if it cannot, then it offers a way of implementing it for all of the above) @@ -25,6 +25,12 @@ A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hype - Or if prefer smashing your keyboard till there's something interesting on the screen. See a first implementation of this *explorational interface*: [orbitmines.com/explorer/github.com/akissinger/chyp](https://orbitmines.com/explorer/github.com/akissinger/chyp). +--- + +## Where is OrbitMines going with this? - i.e. Future inquiries + + + --- ### Some general notes about this project From 967da3afb43c499db7749083037bdc859856fd93 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 16:07:30 +0100 Subject: [PATCH 043/138] 2024/02/10 - Some project logistics for README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 6a027a3..27cf975 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,6 @@ A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hype > [!WARNING] > No proper security audit has yet been done on its current iteration. + +> [!WARNING] +> No proper performance optimizations have been done on its current iteration. From 0e04ebab488f501c6b9d997fef5ddedc9efe3b37 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 16:15:02 +0100 Subject: [PATCH 044/138] 2024/02/10 - Some project logistics for README.md --- README.md | 16 ++++++++++++++++ src/@orbitmines/external/chyp/Chyp.ts | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 27cf975..a9def59 100644 --- a/README.md +++ b/README.md @@ -43,3 +43,19 @@ A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hype > [!WARNING] > No proper performance optimizations have been done on its current iteration. + +--- + +### Local setup + +- Running `orbitmines.com` locally on `http://localhost:3000`: + - ``` + npm install + ``` + - ``` + npm start + ``` +- Running tests. + - ```shell + npm run test -- --watchAll + ``` \ No newline at end of file diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index ebfc02b..2d7fb80 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -8,4 +8,5 @@ * **Why is this interface here?** * * Note that this is mainly here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. Or considered as a legacy translation, which will be accessibly through OrbitMines. - */ \ No newline at end of file + */ + From 7ce978561502c333b8f1b0199336aede2234d68c Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 16:24:21 +0100 Subject: [PATCH 045/138] 2024/02/10 - Some project logistics for README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9def59..4bcb21b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ *Once a Minecraft server, now a research project dedicated to understanding arbitrarily unknown dynamical systems.* ---- +![header](./public/papers/on-orbits-equivalence-and-inconsistencies/images/header.png) ## What is this?, What is OrbitMines?, What are Rays? From d6ee5baa33f95319012c211b5f2ffba058ae81c4 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 18:58:50 +0100 Subject: [PATCH 046/138] 2024/02/10 - Slowly towards a more sensible implementation --- src/@orbitmines/explorer/JS.spec.ts | 19 ++++++ src/@orbitmines/explorer/Ray.spec.ts | 58 +++++++++++++------ src/@orbitmines/explorer/Ray.ts | 48 +++++++++------ src/@orbitmines/external/chyp/Chyp.spec.ts | 13 ++++- src/@orbitmines/external/chyp/Chyp.ts | 29 ++++++++++ .../external/chyp/Chyp_naive_pass.ts | 48 ++++----------- tsconfig.json | 4 +- 7 files changed, 142 insertions(+), 77 deletions(-) create mode 100644 src/@orbitmines/explorer/JS.spec.ts diff --git a/src/@orbitmines/explorer/JS.spec.ts b/src/@orbitmines/explorer/JS.spec.ts new file mode 100644 index 0000000..701eb1a --- /dev/null +++ b/src/@orbitmines/explorer/JS.spec.ts @@ -0,0 +1,19 @@ +import {JS} from "./Ray"; + +describe("JS", () => { + test(".Object", () => { + const ray = JS.Object({ + a: 'b', + position: [0, 1, 2], + func: () => 'c' + }); + + expect(ray.any.a).toBe('b'); + expect(ray.any.test).toBe(undefined); + expect(() => ray.any.undefinedFunction()).toThrow(); + expect(ray.any.position).toEqual([0, 1, 2]); + expect(ray.any.func()).toBe('c'); + }); + + +}); diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 000df04..b78d419 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -1,21 +1,5 @@ -import {JS, Ray, RayType} from "./Ray"; -import {PreventsImplementationBug} from "./errors/errors"; +import {Ray, RayType} from "./Ray"; -describe("JS", () => { - test(".Object", () => { - const ray = JS.Object({ - a: 'b', - position: [0, 1, 2], - func: () => 'c' - }); - - expect(ray.any.a).toBe('b'); - expect(ray.any.test).toBe(undefined); - expect(() => ray.any.undefinedFunction()).toThrow(); - expect(ray.any.position).toEqual([0, 1, 2]); - expect(ray.any.func()).toBe('c'); - }) -}); describe("Ray", () => { // test(".vertex.#.debug", () => { // const a = Ray.vertex().as_reference(); @@ -77,6 +61,26 @@ describe("Ray", () => { expect(initial.is_reference()).toBe(false); expect(initial.type).toBe(RayType.INITIAL); }); + test(".initial.#", () => { + /** [ |-?] */ const initial = Ray.initial().as_reference(); + + expect(initial.self.initial.is_none()).toBe(true); + expect(initial.self).not.toBe(initial.self.self); // If self-referential, that means none. + + expect(initial.self.terminal.initial).toBe(initial.self); + + expect(initial.self.is_none()).toBe(false); + expect(initial.self.self.is_none()).toBe(true); + + expect(initial.is_some()).toBe(true); + expect(initial.self.terminal.is_none()).toBe(false); + + expect(initial.is_initial()).toBe(true); + expect(initial.is_vertex()).toBe(false); + expect(initial.is_terminal()).toBe(false); + expect(initial.is_reference()).toBe(false); + expect(initial.type).toBe(RayType.INITIAL); + }); test(".vertex.terminal.#", () => { /** [--|--] */ const vertex = Ray.vertex(); /** [ |--] */ const terminal = vertex.terminal.as_reference(); @@ -100,6 +104,26 @@ describe("Ray", () => { expect(terminal.is_reference()).toBe(false); expect(terminal.type).toBe(RayType.TERMINAL); }); + test(".terminal.#", () => { + /** [--| ] */ const terminal = Ray.terminal().as_reference(); + + expect(terminal.self.terminal.is_none()).toBe(true); + expect(terminal.self).not.toBe(terminal.self.self); // If self-referential, that means none. + + expect(terminal.self.initial.terminal).toBe(terminal.self); + + expect(terminal.self.is_none()).toBe(false); + expect(terminal.self.self.is_none()).toBe(true); + + expect(terminal.is_some()).toBe(true); + expect(terminal.self.initial.is_none()).toBe(false); + + expect(terminal.is_terminal()).toBe(true); + expect(terminal.is_vertex()).toBe(false); + expect(terminal.is_initial()).toBe(false); + expect(terminal.is_reference()).toBe(false); + expect(terminal.type).toBe(RayType.TERMINAL); + }); test(".None", () => { /** [ ] */ const ray = Ray.None(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 4890db0..0c9b519 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,9 +1,5 @@ -import _, {initial} from "lodash"; +import _ from "lodash"; import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; -import {InterfaceOptions} from "./OrbitMinesExplorer"; -import {value} from "../../lib/typescript/React"; -import {current} from "../../profiles/FadiShawki/FadiShawki2"; -import {debug} from "node:util"; // SHOULDNT CLASSIFY THESE? @@ -20,6 +16,20 @@ export type Arbitrary = (...args: any[]) => T; export type Constructor = new (...args: any[]) => T; export type ParameterlessConstructor = new () => T; +export function initial() { + + return function (target: any, propertyKey: string): any { + Object.defineProperty(target, propertyKey, { + get: (): any => { return target.initial; }, + set: (value) => { + target.initial = value; + }, + // enumerable: true, + // configurable: true + }); + } +} + /** * https://en.wikipedia.org/wiki/Homoiconicity */ @@ -31,6 +41,7 @@ export interface PossiblyHomoiconic> { export interface AbstractDirectionality { initial: Arbitrary, vertex: Arbitrary, terminal: Arbitrary } +// TODO: better debug export type DebugResult = { [label: string]: DebugRay } export type DebugRay = { label: string, @@ -63,6 +74,12 @@ export type DebugRay = { * TODO: Can do some workaround overloading through properties, at least for +/- * * TODO: Singlke keybind for now to show/hide the ray disambiguation or 'dead edges/..'/ + * + * + * TODO: Automatically implement any function with paramters, as being callable from a ray of that size.. + * + * + * TODO: Consistency of Arbitrary vs non-arbitrary. */ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? implements @@ -79,18 +96,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? protected _vertex: Arbitrary; get vertex(): Ray { return this._vertex(); } set vertex(vertex: Arbitrary) { this._vertex = vertex; } protected _terminal: Arbitrary; get terminal(): Ray { return this._terminal(); } set terminal(terminal: Arbitrary) { this._terminal = terminal; } - get self(): Ray { - // if (!this.vertex.is_none()) - // throw new PreventsImplementationBug('Preventing bugs, .self is used for the assumption of a reference..'); - // - return this.vertex; - }; - set self(self: Arbitrary) { - // if (!this.is_reference()) - // throw new PreventsImplementationBug('Preventing bugs, .self is used for the assumption of a reference..'); - // - this.vertex = self; - } + get self(): Ray { return this.vertex; }; set self(self: Arbitrary) { this.vertex = self; } [index: number]: Ray; @@ -147,6 +153,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** [--?--] */ return vertex; } + /** [ |-?] */ static initial = () => Ray.vertex().initial; + /** [?-| ] */ static terminal = () => Ray.vertex().terminal; static size = (of: number, value: any = undefined): Ray => { let current = Ray.vertex().as_reference(); // TODO; This sort of thing should be lazy @@ -232,6 +240,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // return Arbitrary.Fn(() => length(of, value).resolve().at_terminal(index)); // } // + // step = this.at; ??? at = (steps: number | Ray | Arbitrary): Ray => { throw new NotImplementedError(); } // // export const permutation = (permutation: number | undefined, of: number): Arbitrary> => at( @@ -327,7 +336,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return this; } - protected property = (property: string | symbol, _default?: any): any => this.any[property] ??= _default; // TODO: Can this be prettier?? + protected property = (property: string | symbol, _default?: any): any => this.any[property] ??= (_default ?? Ray.None()); // TODO: Can this be prettier?? protected _proxy: any; protected _dirty_store: { [key: string | symbol]: object } = {} @@ -388,6 +397,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; } + push_back = (ray: Ray) => { throw new NotImplementedError(); } + push_front = (ray: Ray) => { throw new NotImplementedError(); } + // length: number; // // concat(...items: ConcatArray[]): Ray[]; diff --git a/src/@orbitmines/external/chyp/Chyp.spec.ts b/src/@orbitmines/external/chyp/Chyp.spec.ts index 26b5fc0..9aaf12a 100644 --- a/src/@orbitmines/external/chyp/Chyp.spec.ts +++ b/src/@orbitmines/external/chyp/Chyp.spec.ts @@ -1,10 +1,17 @@ import {Ray} from "../../explorer/Ray"; +import {Chyp} from "./Chyp"; describe("Chyp", () => { - describe("Graph", () => { - test(".o", () => { + describe(".Graph", () => { + test(".set_inputs", () => { + const graph = new Chyp.Graph() + .set_inputs(Ray.vertex().o({ js: 'B' }).as_arbitrary()) + .set_inputs(Ray.vertex().o({ js: 'A' }).as_arbitrary()); - expect('a').toBe('c'); + expect(graph.inputs.any.js).toBe('A'); + expect(graph.initial.any.js).toBe('A'); + expect(graph.inputs.any.js).toBe(graph.initial.any.js); + expect(graph.inputs).toBe(graph.initial); }) }); diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index 2d7fb80..a483968 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1,3 +1,5 @@ +import {Arbitrary, initial, Ray, second} from "../../explorer/Ray"; + /** * An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Rays. * @@ -10,3 +12,30 @@ * Note that this is mainly here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. Or considered as a legacy translation, which will be accessibly through OrbitMines. */ +export namespace Chyp { + + export type VData = Vertex; class Vertex extends Ray { + + } + + export type EData = Edge; class Edge extends Ray { + + } + + export class Graph extends Ray { + + /** + * These are all just slightly differently abstracted in TypeScript here to make them a little more native. + */ + // Graph.inputs = Ray.initial + get inputs(): Ray { return this.initial; } set inputs(ray: Arbitrary) { this.initial = ray; } + set_inputs = (ray: Arbitrary): Graph => { this.inputs = ray; return this; } + add_inputs = (ray: Ray): Graph => { this.inputs.continues_with(ray); return this; } + // Graph.inputs = Ray.terminal + get outputs(): Ray { return this.terminal; } set outputs(ray: Arbitrary) { this.terminal = ray; } + set_outputs = (ray: Arbitrary): Graph => { this.outputs = ray; return this; } + add_outputs = (ray: Ray): Graph => { this.outputs.continues_with(ray); return this; } + + } + +} \ No newline at end of file diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts index 76d66ab..9ac95e1 100644 --- a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts +++ b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts @@ -2,14 +2,6 @@ import {JS, Ray} from "../../explorer/Ray"; import {NotImplementedError} from "../../explorer/errors/errors"; /** - * An interface from Aleks Kissinger's Chyp (Cospans of HYPergraphs) to Rays. - * GitHub: https://github.com/akissinger/chyp - * - * A simple way of phrasing this conversion, is that the concept of a 'Vertex', 'Edge', 'Graph', 'Rule', ..., 'Rewrite' are merged into one thing: a Ray. - * - * NOTE: - * This is just here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. - * * - The .copy()'s are implemented on Ray. * * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. @@ -368,43 +360,23 @@ export class Graph extends Ray { // TODO: Can these be overlaoded in properties using -=, += in TS? - /** - * Append `inp` to the inputs of the graph. - * - * @param inp The list of vertex integer identifiers of the appended inputs. - */ - add_inputs = (inp = list(int)): Ray => { - this.inputs.continues_with(inp); // TODO: Perhaps splat - } - /** - * Append `outp` to the outputs of the graph. - * - * @param outp The list of vertex integer identifiers of the appended outputs. - */ - add_outputs = (outp = list(int)): Ray => { - this.outputs.continues_with(outp); // TODO: Perhaps splat - } - // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) + // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. - // Return the list of vertex ids of the graph inputs. - get inputs(): Ray { throw new NotImplementedError(); } - // Return the list of vertex ids of the graph outputs. - get outputs(): Ray { throw new NotImplementedError(); } + + // set function: // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs - set inputs(ray = list(int)) { throw new NotImplementedError(); } - set outputs(ray = list(int)) { throw new NotImplementedError(); } + // inputs =, outputs = + // for the add functions: // TODO: Perhaps splat + // also for add // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) + - // TODO: Move these to a "reference-like" structure, need to be on VData.. - /** - * These are all just slightly differently abstracted in TypeScript here to make them a little more native. - */ - set_inputs = (inp = list(int)): Ray => this.inputs = inp; - set_outputs = (outp = list(int)): Ray => this.outputs = outp; + + // TODO: Move these to a "reference-like" structure, need to be on VData.. /** * All these are just delegations from some Vertex/Edge structure. @@ -975,7 +947,7 @@ export class Chyp extends Ray { * * return gen('_redistributer', domain, codomain) */ - + } /** diff --git a/tsconfig.json b/tsconfig.json index 4309a65..16c74f0 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,9 @@ "isolatedModules": true, "suppressImplicitAnyIndexErrors": false, "noEmit": true, - "jsx": "react-jsx" + "jsx": "react-jsx", + "emitDecoratorMetadata": true, + "experimentalDecorators": true }, "include": [ "src" From 2dffa4ee76b23d2aab79dd70f4745b418e334639 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 20:49:05 +0100 Subject: [PATCH 047/138] 2024/02/10 - Slowly towards a more sensible implementation --- src/@orbitmines/explorer/Ray.ts | 29 +++- src/@orbitmines/external/chyp/Chyp.spec.ts | 13 +- src/@orbitmines/external/chyp/Chyp.ts | 79 ++++++++++- .../external/chyp/Chyp_naive_pass.ts | 130 ++---------------- 4 files changed, 124 insertions(+), 127 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 0c9b519..c774547 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -76,7 +76,7 @@ export type DebugRay = { * TODO: Singlke keybind for now to show/hide the ray disambiguation or 'dead edges/..'/ * * - * TODO: Automatically implement any function with paramters, as being callable from a ray of that size.. + * * * * TODO: Consistency of Arbitrary vs non-arbitrary. @@ -172,6 +172,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // as_option = (): Ray => Option.Some(this); as_arbitrary = (): Arbitrary => () => this; + // TODO AS += through property continues_with = (b: Ray): Ray => { // TODO: contiues_with is just composing vertices.. @@ -225,10 +226,21 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO NEEDS TO CHECK IF THERE'S SOME INITIAL DEFIEND ; for defining if it has halted + get first(): Ray { throw new NotImplementedError(); } + get last(): Ray { throw new NotImplementedError(); } + protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother this.self = b.as_arbitrary(); b.self = this.as_arbitrary(); } + // TODO: I Don't like this name, but it needs to get across that any equivalency, or any equivalency check for that necessarily, is local. And I want more equivalences, I run more of this method. + // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. + is_vertex_equivalent = (b: Ray) => { + // TODO; in the case of a list, each individually, again, additional structure... + } + // TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? + is_equivalent = (b: Ray): boolean => { return false; } // TODOl: Current references assume you can't go inside vertex.. + // TODO implement .not?? // TODO: Perhaps locally cache count?? - no way to ensure globally coherenct get count(): Ray { throw new NotImplementedError() } @@ -236,6 +248,19 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO; Could return the ignorant reference to both instances, or just the result., .. copy = (): Ray => { throw new NotImplementedError() } + // @alias('converse', 'opposite', 'swap') + get reverse(): Ray { + const copy = this;//TODO.copy(); + + // TODO: Do we do this lazy by default? Just using refs??? - Or abstract this elsewhere to decide what to do + const swap = copy.initial; + copy.initial = copy.terminal.as_arbitrary(); + copy.terminal = swap.as_arbitrary(); + // TODO: This doesn't actually work + + return copy; + } + // export const at = (index: number, of: number, value: any = undefined): Arbitrary> => { // return Arbitrary.Fn(() => length(of, value).resolve().at_terminal(index)); // } @@ -296,6 +321,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ } + // ___compute = () + *traverse(): Generator {} /** diff --git a/src/@orbitmines/external/chyp/Chyp.spec.ts b/src/@orbitmines/external/chyp/Chyp.spec.ts index 9aaf12a..fa05836 100644 --- a/src/@orbitmines/external/chyp/Chyp.spec.ts +++ b/src/@orbitmines/external/chyp/Chyp.spec.ts @@ -12,8 +12,19 @@ describe("Chyp", () => { expect(graph.initial.any.js).toBe('A'); expect(graph.inputs.any.js).toBe(graph.initial.any.js); expect(graph.inputs).toBe(graph.initial); - }) + }); }); + describe(".Rule", () => { + test(".name", () => { + let rule = new Chyp.Rule(); + rule.name = 'test'; + + expect(rule.name).toBe('test'); + expect(rule.reverse.any.name).toBe('-test'); + expect(rule.reverse.reverse.any.name).toBe('test'); + + }); + }); }); diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index a483968..a128617 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1,4 +1,4 @@ -import {Arbitrary, initial, Ray, second} from "../../explorer/Ray"; +import {Arbitrary, Ray} from "../../explorer/Ray"; /** * An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Rays. @@ -12,21 +12,90 @@ import {Arbitrary, initial, Ray, second} from "../../explorer/Ray"; * Note that this is mainly here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. Or considered as a legacy translation, which will be accessibly through OrbitMines. */ +/** TODO errors probably hooked as a boolean, one successful the other not */ +export class GraphError extends Error {} +export class RuleError extends Error {} +export class RuntimeError extends Error {} +export class StopIteration extends Error {} + export namespace Chyp { - export type VData = Vertex; class Vertex extends Ray { + export type VData = Vertex; export class Vertex extends Ray { + + // Vertex.in_edges = Ray.initial + get in_edges(): Ray { return this.initial; } set in_edges(ray: Arbitrary) { this.initial = ray; } + + // Vertex.out_edges = Ray.terminal + get out_edges(): Ray { return this.terminal; } set out_edges(ray: Arbitrary) { this.terminal = ray; } } - export type EData = Edge; class Edge extends Ray { + export type EData = Edge; export class Edge extends Ray { + + // Edge.source = Ray.initial + get source(): Ray { return this.initial; } set source(ray: Arbitrary) { this.initial = ray; } + get s(): Ray { return this.initial; } set s(ray: Arbitrary) { this.initial = ray; } + + // Edge.targets = Ray.terminal + get target(): Ray { return this.terminal; } set target(ray: Arbitrary) { this.terminal = ray; } + get t(): Ray { return this.terminal; } set t(ray: Arbitrary) { this.terminal = ray; } } - export class Graph extends Ray { + export class Match extends Ray { + + // Match.domain = Ray.initial + get domain(): Ray { return this.initial; } set domain(ray: Arbitrary) { this.initial = ray; } + + // Match.codomain = Ray.terminal + get codomain(): Ray { return this.terminal; } set codomain(ray: Arbitrary) { this.terminal = ray; } + + } + + export class Rule extends Ray { + + // Rule.lhs = Ray.initial + get lhs(): Ray { return this.initial; } set lhs(ray: Arbitrary) { this.initial = ray; } + + // Rule.rhs = Ray.terminal + get rhs(): Ray { return this.terminal; } set rhs(ray: Arbitrary) { this.terminal = ray; } /** - * These are all just slightly differently abstracted in TypeScript here to make them a little more native. + * TODO: We can use the same implementation to rewrite where there's not necessarily a match between initial/terminal side of a rule. + * + * TODO: In general, we can just assume each lhs, has some link to some rhs, and not go through 'The Rule', and simply if lhs terminates, it terminates, if additional ones are initialized through rhs, so be it. - Set this up after this implementation where we reference an entire thing from a single perspective. */ + validate = () => { + // TODO: Call from somewhere. + + if (!this.initial.is_equivalent(this.terminal)) + throw new RuleError('LHS (Initial) !== RHS (Terminal)'); + + // TODO: Or each check separately + // if (!this.initial.initial.is_equivalent(this.terminal.initial)) + // throw new RuleError('Initial.Initial (LHS.Domain) !== Terminal.Initial (RHS.Domain)'); + // if (!this.initial.terminal.is_equivalent(this.terminal.terminal)) + // throw new RuleError('Initial.Terminal (LHS.Codomain) !== Terminal.Terminal (RHS.Codomain)'); + } + + name = this.property('name', ''); + + override get reverse(): Ray { + // TODO remove this hacky thing - just tries to us -a / a + + const name = this.name.startsWith('-') ? this.name.substring(1) : `-${this.name}`; + + return super.reverse.o({ name }); + } + + dpo = (match: Match): Ray => { + + } + + } + + export class Graph extends Ray { + // Graph.inputs = Ray.initial get inputs(): Ray { return this.initial; } set inputs(ray: Arbitrary) { this.initial = ray; } set_inputs = (ray: Arbitrary): Graph => { this.inputs = ray; return this; } diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts index 9ac95e1..faa327a 100644 --- a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts +++ b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts @@ -70,14 +70,6 @@ export class ValueError extends Error {} */ export const VType = JS.Iterable([str, None]); -/** - * An error occurred in the graph backend. - * - * TODO probably hooked as a boolean, one successful the other not - */ -export class GraphError extends Error {} -export class RuleError extends Error {} - /** * Used for debugging (the matcher) */ @@ -113,15 +105,6 @@ export class VData extends Ray { highlight = this.property('highlight', bool(False)) value = this.property('value') - /** - * Integer identifiers of input and output hyperedges of this vertex - useful for finding neighbouring hyperedges. - * - * TODO ; // set[int] = set() - * TODO ; these are just the initial/terminal sides of a Ray. they're just duplicated - */ - get in_edges(): Ray { throw new NotImplementedError(); } - get out_edges(): Ray { throw new NotImplementedError(); } - /** * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. */ @@ -135,8 +118,7 @@ export class VData extends Ray { // TODO: Probably generalizable /** - * - * @param other + * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. */ merge = (other: VData): Ray => { // TODO: other is destroyed @@ -186,19 +168,8 @@ export class VData extends Ray { } -/** - * Data associated with a single edge. - */ export class EData extends Ray { - get source() { return this.s }; - get target() { return this.t }; - - // TODO: this is just the initial frame - get s(): Ray { throw new NotImplementedError(); } - // TODO: this is just the terminal frame - get t(): Ray { throw new NotImplementedError(); } - fg = this.property('bg', Color()); bg = this.property('bg', Color()); x = this.property('y', int(0)); @@ -374,46 +345,12 @@ export class Graph extends Ray { // also for add // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) - - - // TODO: Move these to a "reference-like" structure, need to be on VData.. - - /** - * All these are just delegations from some Vertex/Edge structure. - */ - // .vertices - num_vertices = (): Ray => this.vertices().count.as_int(); - - // .edges - num_edges = (): Ray => this.edges().count.as_int(); - - // .vertex_data - is_input = (v = int): Ray => this.vertex_data(v).is_input(); - is_output = (v = int): Ray => this.vertex_data(v).is_output(); - is_boundary = (v = int): Ray => this.vertex_data(v).is_boundary(); - in_edges = (v = int): Ray => this.vertex_data(v).in_edges; - out_edges = (v = int): Ray => this.vertex_data(v).out_edges; - - // .edge_data - source = (e = int): Ray => this.edge_data(e).source; - target = (e = int): Ray => this.edge_data(e).target; - edge_domain = (edge_id = int): Ray => this.edge_data(edge_id).domain(); - edge_codomain = (edge_id = int): Ray => this.edge_data(edge_id).codomain(); - /** * Return vertices that lie on a directed path from any of `vs`. * // TODO: Just traverse the rays, deduplicate using the index */ successors = (ray: Ray): Ray => ray.next; - /** - * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. - * - * @param v Integer identifier of the vertex into which to merge `w`. - * @param w Integer identifier of the vertex to merge into `v`. - */ - merge_vertices = (v = int, w = int): Ray => this.vertex_data(v).merge(this.vertex_data(w)); - /** * Split a vertex into copies for each input, output, and tentacle. * @@ -713,7 +650,6 @@ export class Graph extends Ray { .filter(edge => edges.includes(edge)) .all(edge => edge.cast().highlight = bool(true)); - } /** @@ -1083,14 +1019,11 @@ export class MainWindow extends Ray { // TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? export class Match extends Ray { - get domain(): Graph { throw new NotImplementedError(); } - get codomain(): Graph { throw new NotImplementedError(); } get vertex_map(): Ray { throw new NotImplementedError(); } get vertex_image(): Ray { throw new NotImplementedError(); } get edge_map(): Ray { throw new NotImplementedError(); } get edge_image(): Ray { throw new NotImplementedError(); } - __init__ = (): Ray => { throw new NotImplementedError(); } __str__ = (): Ray => { // (f'\tVertex map: {str(self.vertex_map)}' // + f'\n\tEdge map: {str(self.edge_map)}') @@ -1512,46 +1445,9 @@ export class Matches extends Ray { } export class Rule extends Ray { - get lhs(): Graph { throw new NotImplementedError(); } - get rhs(): Graph { throw new NotImplementedError(); } - /** - * TODO: Put the name on each side of the rule, not the '-' hacky thing - */ - get name(): Ray { throw new NotImplementedError(); } get equiv(): Ray { throw new NotImplementedError(); } - __init__ = (name = str(''), equiv = bool(True)): Ray => { - // TODO: Maybe just move exception to a method on this thing - - if (this.lhs.domain !== this.rhs.domain) // TODO: !== - throw new RuleError(`Inputs must match on LHS and RHS of rule (${this.rhs.domain} != ${this.lhs.domain})`); - - if (this.lhs.codomain !== this.rhs.codomain) - throw new RuleError(`Outputs must match on LHS and RHS of rule (${this.rhs.codomain} != ${this.lhs.codomain})`) - - - throw new NotImplementedError(); - - } - - copy = (): Ray => { throw new NotImplementedError(); } - - // TODO: Could put this on ray, generalize to swapping - converse = (): Rule => { - // TODO remove this hacky thing - just tries to us -a / a - const name = this.name.as_string().startsWith('-') ? this.name.substring(1) : `-${this.name}`; - - const converse: Rule = this.copy().cast(); // TODO equiv=True? - converse.name = name; - - // TODO: Wont work, we just should swap initial/terminal;\ - //swap?? or change direction.. - // const swap = converse.rhs; - // converse.rhs = converse.lhs; - // converse.lhs = swap; - return converse; - } /** * Returns True if boundary on lhs embeds injectively @@ -1591,8 +1487,8 @@ export class Rule extends Ray { return; } - const rule_input = this.lhs.vertex_data(rule_vertex).in_indices; - const rule_output = this.lhs.vertex_data(rule_vertex).out_indices; + const rule_input = rule_vertex.in_indices; + const rule_output = rule_vertex.out_indices; if (rule_input.count.as_int() === 1 && rule_output === 1) { const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); @@ -1661,25 +1557,19 @@ export class Rule extends Ray { return replacement; } - /** - * Apply the given rewrite r to at match m and return the first result - * - * This is a convience wrapper for `dpo` for when the extra rewrite data isn't needed. - */ - rewrite = (match: Match): Graph => { - // TODO: except StopIteration: - // raise RuntimeError("Rewrite has no valid context") - - const result: Match = this.dpo(match).first().cast(); - return result.codomain; - } - // TODO: Can probably just match Rule=Graph, and use only one of these methods?? /** * Return matches of the left side of `rule` into `graph`. */ match = (other: Graph, convex: boolean = true): Matches => new Matches(this.lhs, other, convex); + /** + * Apply the given rewrite r to at match m and return the first result + * + * This is a convenience wrapper for `dpo` for when the extra rewrite data isn't needed. + */ + rewrite = (match: Match): Ray => this.dpo(match).first.terminal; // .first.codomain + // TODO; Though .first is used here, something like .any is more appropriate in the sense of: Don't care which one first, just something. } export class RewriteState extends Ray { From 3cb4cc3478aed4ec0382b0d38675133dc1455be6 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 10 Jan 2024 22:17:22 +0100 Subject: [PATCH 048/138] 2024/02/10 - Slowly towards a more sensible implementation --- src/@orbitmines/explorer/Ray.spec.ts | 36 +++++-- src/@orbitmines/explorer/Ray.ts | 95 ++++++++++++++++++- src/@orbitmines/external/chyp/Chyp.spec.ts | 2 +- .../external/chyp/Chyp_naive_pass.ts | 64 +------------ 4 files changed, 122 insertions(+), 75 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index b78d419..7064462 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -1,16 +1,16 @@ import {Ray, RayType} from "./Ray"; describe("Ray", () => { -// test(".vertex.#.debug", () => { -// const a = Ray.vertex().as_reference(); -// const b = Ray.vertex().as_reference(); -// a.continues_with(b); -// -// const debug = {}; -// a.debug(debug); -// -// expect(debug).toEqual('') -// }) + // test(".vertex.#.debug", () => { + // const a = Ray.vertex().as_reference(); + // const b = Ray.vertex().as_reference(); + // a.continues_with(b); + // + // const debug = {}; + // a.debug(debug); + // + // expect(debug).toEqual('') + // }) test(".o", () => { const ray = Ray.vertex().o({ a: 'b', @@ -25,6 +25,22 @@ describe("Ray", () => { expect(ray.any.func()).toBe('c'); }) + // test(".[vertex, vertex].#.compose", () => { + // /** [--|--] */ const vertex = Ray.vertex().as_reference(); + // vertex.initial.o({ js: 'A' }); + // vertex.terminal.o({ js: 'B' }); + // + // expect(vertex.compose.) + // }); + test(".vertex.#.continues_with(.vertex.#)", () => { + /** [--|--] */ const B = + Ray.vertex().o({ js: 'A' }).as_reference() + .continues_with(Ray.vertex().o({ js: 'B'}).as_reference()); + + expect(B.type).toBe(RayType.VERTEX); + expect(B.self.self.self.any.js).toBe('B'); + // expect(B.self.self.self.initial.initial.any.js).toBe('A'); + }); test(".vertex.#", () => { /** [--|--] */ const vertex = Ray.vertex().as_reference(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index c774547..f2c914d 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -86,7 +86,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? PossiblyHomoiconic, AsyncIterable, - Iterable//, + Iterable // Array // Dict { @@ -134,8 +134,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. */ - is_none = (): boolean => this.self === this.self.self; + is_none = (): boolean => this.is_orbit(this.self, this.self.self); + protected is_orbit = (a: Ray, b: Ray) => a === b; // is, ..., appears equal. protected self_reference = () => this; is_some = (): boolean => !this.is_none(); @@ -230,6 +231,17 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? get last(): Ray { throw new NotImplementedError(); } protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother + switch (this.type) { + case RayType.REFERENCE: + break; + case RayType.INITIAL: + break; + case RayType.TERMINAL: + break; + case RayType.VERTEX: + break; + } + this.self = b.as_arbitrary(); b.self = this.as_arbitrary(); } @@ -302,6 +314,85 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // [[a,d,g],[b,e,h],[c,f,i]] zip = (): Ray => { throw new NotImplementedError(); } + /** + * Compose structures defined at .initial with those at .terminal, dropping the vertex. ; or if done non-ignorantly. Composing them on another level, ignoring to this vertex. TODO: Allow this freedom + */ + get merge(): Ray { + // concat initial.a + initial.b, terminal.a + terminal.b + // then: either destroy a/b, merge structure... etc.. + // Chyp: destroy b + + // this.initial.equivalent(other.initial); + // this.terminal.equivalent(other.terminal); + + /* + + vd = self.vertex_data(v) + # print("merging %s <- %s" % (v, w)) + + # Where vertex `w` occurs as an edge target, replace it with `v` + for e in self.in_edges(w): + ed = self.edge_data(e) + ed.t = [v if x == w else x for x in ed.t] + vd.in_edges.add(e) + + # Where vertex `w` occurs as an edge source, replace it with `v` + for e in self.out_edges(w): + ed = self.edge_data(e) + ed.s = [v if x == w else x for x in ed.s] + vd.out_edges.add(e) + + # Wherever `w` occurs on the graph boundary, replace it with `v` + self.set_inputs([v if x == w else x for x in self.inputs]) + self.set_outputs([v if x == w else x for x in self.outputs]) + + # Remove references to `w` from the graph + self.remove_vertex(w) + + */ + throw new NotImplementedError(); + } + // @alias('merge') ?? + get compose(): Ray { + switch (this.type) { + case RayType.REFERENCE: + case RayType.INITIAL: + case RayType.TERMINAL: { + throw new NotImplementedError(); + } + case RayType.VERTEX: { + const vertex = this.self; + + // TODO; Implement as restrictive case for Chyp + { + // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) + // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); + + // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. + // if (this.self.initial.is_equivalent(this.self.terminal)) + // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output + } + + /** + * A simple case of what we want to solve here. + * + * Initial Terminal + * ... ... + * [--| ] [ |--] + * [--| ] [ |--] + * [--| ] [ |--] + * [ |--] [--|--] [--| ] + * vertex + * + * And recursively (arbitrarily) match initial/terminal structures. + */ + + throw new NotImplementedError(); + } + } + throw new NotImplementedError(); + } + // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS apply = (func: Ray) => { diff --git a/src/@orbitmines/external/chyp/Chyp.spec.ts b/src/@orbitmines/external/chyp/Chyp.spec.ts index fa05836..453ef05 100644 --- a/src/@orbitmines/external/chyp/Chyp.spec.ts +++ b/src/@orbitmines/external/chyp/Chyp.spec.ts @@ -22,7 +22,7 @@ describe("Chyp", () => { expect(rule.name).toBe('test'); expect(rule.reverse.any.name).toBe('-test'); - expect(rule.reverse.reverse.any.name).toBe('test'); + // expect(rule.reverse.reverse.any.name).toBe('test'); }); }); diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts index faa327a..23226b4 100644 --- a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts +++ b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts @@ -119,39 +119,10 @@ export class VData extends Ray { /** * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. + * + * TODO; particular sort of composing */ merge = (other: VData): Ray => { - // TODO: other is destroyed - // TODO: Vertices - // this.initial.equivalent(other.initial); - // this.terminal.equivalent(other.initial); - - /* - - vd = self.vertex_data(v) - # print("merging %s <- %s" % (v, w)) - - # Where vertex `w` occurs as an edge target, replace it with `v` - for e in self.in_edges(w): - ed = self.edge_data(e) - ed.t = [v if x == w else x for x in ed.t] - vd.in_edges.add(e) - - # Where vertex `w` occurs as an edge source, replace it with `v` - for e in self.out_edges(w): - ed = self.edge_data(e) - ed.s = [v if x == w else x for x in ed.s] - vd.out_edges.add(e) - - # Wherever `w` occurs on the graph boundary, replace it with `v` - self.set_inputs([v if x == w else x for x in self.inputs]) - self.set_outputs([v if x == w else x for x in self.outputs]) - - # Remove references to `w` from the graph - self.remove_vertex(w) - - */ - throw new NotImplementedError(); } @@ -493,41 +464,10 @@ export class Graph extends Ray { compose = (other: Graph): Ray => { // TODO Just matching outputs and inputs.. - const a = this; - const b = other; - // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" - const compose: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] - - // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. - - // TODO: This is just again an equivalence type check on the ends of the ray // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs - { - if (compose.initial.count.as_int() !== compose.terminal.count.as_int()) - throw new GraphError(`Codomain ${a.codomain()} does not match domain ${b.domain()}`); // TODO ; a/b ref will be removed - - /** - * for output_id, input_id in zip(self_outputs, other_inputs): - * output_data = self.vertex_data(output_id) - * input_data = other.vertex_data(input_id) - * if output_data.vtype != input_data.vtype: - * if not (output_data.infer_type or input_data.infer_type): - * raise GraphError( - * f'Codomain {self.codomain()} does not ' - * + f'match domain {other.domain()}' - * ) - * if output_data.size != input_data.size: - * if not (output_data.infer_size or input_data.infer_size): - * raise GraphError( - * f'Codomain {self.codomain()} does not ' - * + f'match domain {other.domain()}' - * ) - */ - } - /** * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. */ From 475a46cdccf7950cddf35ea7fd915a6eccb1fb2c Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 11 Jan 2024 15:02:22 +0100 Subject: [PATCH 049/138] 2024/02/11 - Debug playground setup --- src/@orbitmines/explorer/Ray.spec.ts | 10 + src/@orbitmines/explorer/Ray.ts | 22 + .../explorer/debug/DebugCanvas.tsx | 187 + src/@orbitmines/external/chyp/Chyp.ts | 3 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 1 - .../external/chyp/Chyp_naive_pass.ts | 3174 ++++++++--------- src/App.tsx | 6 +- 7 files changed, 1812 insertions(+), 1591 deletions(-) create mode 100644 src/@orbitmines/explorer/debug/DebugCanvas.tsx diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 7064462..2bee84e 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -53,6 +53,10 @@ describe("Ray", () => { expect(vertex.is_vertex()).toBe(true); expect(vertex.is_terminal()).toBe(false); expect(vertex.is_reference()).toBe(false); + + expect(vertex.self).toBe(vertex.self.initial.terminal); + expect(vertex.self).toBe(vertex.self.terminal.initial); + expect(vertex.self).toBe(vertex.self.initial.as_reference().self.terminal); }); test(".vertex.initial.#", () => { /** [--|--] */ const vertex = Ray.vertex(); @@ -83,6 +87,9 @@ describe("Ray", () => { expect(initial.self.initial.is_none()).toBe(true); expect(initial.self).not.toBe(initial.self.self); // If self-referential, that means none. + expect(initial.self).toBe(initial.self.terminal.initial); + expect(initial.self.terminal).toBe(initial.self.terminal.terminal.initial); + expect(initial.self.terminal.initial).toBe(initial.self); expect(initial.self.is_none()).toBe(false); @@ -126,6 +133,9 @@ describe("Ray", () => { expect(terminal.self.terminal.is_none()).toBe(true); expect(terminal.self).not.toBe(terminal.self.self); // If self-referential, that means none. + expect(terminal.self).toBe(terminal.self.initial.terminal); + expect(terminal.self.initial).toBe(terminal.self.initial.initial.terminal); + expect(terminal.self.initial.terminal).toBe(terminal.self); expect(terminal.self.is_none()).toBe(false); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index f2c914d..5c21fe5 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -459,6 +459,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? protected _proxy: any; protected _dirty_store: { [key: string | symbol]: object } = {} protected proxy = (constructor?: ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: + // TODO: IMPLEMENT SPLAT... {...ray.any} return this._proxy ??= new Proxy(this, { get(self: Ray, p: string | symbol, receiver: any): any { @@ -477,6 +478,27 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }) as T; } + + //TODO USED FOR DEBUG NOW + move = (func: (self: Ray) => Ray, traversed: Ray[]): Ray => { + const target_ray = func(this.self); + const target = target_ray.as_reference().o({ + ...this._dirty_store, + position: + target_ray.any.position + ?? this.self.any.position + ?? [0, 0, 0] + }); + console.log('move', `${this.self.label.split(' ')[0]} -> ${target.self.label.split(' ')[0]}`); + + if (!target_ray.any.traversed) { + traversed.push(target); + target_ray.any.traversed = true; + } + + return target; + } + debug = (c: DebugResult): DebugRay => { if (c[this.label] !== undefined) return c[this.label]!; diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx new file mode 100644 index 0000000..aecd5be --- /dev/null +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -0,0 +1,187 @@ +import IEventListener from "../../js/react/IEventListener"; +import {VisualizationCanvas} from "../Visualization"; +import React, {useEffect, useReducer, useRef, useState} from "react"; +import {useHotkeys} from "../../js/react/hooks/useHotkeys"; +import {Ray, RayType} from "../Ray"; +import { + _Continuation, _Vertex, + add, + AutoRay, + AutoVertex, + InterfaceOptions, + Line, + SimpleRenderedRay, + torus +} from "../OrbitMinesExplorer"; +import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; +import {useThree} from "@react-three/fiber"; +import {Stats, StatsGl} from "@react-three/drei"; +import _ from "lodash"; +import {NotImplementedError} from "../errors/errors"; + +const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { + const ref = useRef(); + const hotkeyConfig = useHotkeys(); + + const { + gl: renderer, + camera, + scene, + raycaster + } = useThree(); + + const space_between = 20 * scale; + + const [Interface] = useState(Ray.vertex().o({ + selection: Ray + .vertex().o({ position: [0, 0, 0], scale, color: 'orange' }) + .initial.o({ position: [-space_between, 0, 0] }).terminal + .terminal.o({ position: [space_between, 0, 0 ]}).initial + .as_reference().o({ + position: [0, 0, 0], + scale, + rotation: [0, 0, Math.PI / 6 ], + color: '#555555' + }), + rays: [] as Ray[], + stats: false, + controls: Ray.vertex().o({ + hotkeys: [ + { + combo: "a", global: true, label: "", onKeyDown: () => { + Interface.any.selection = Interface.any.selection.move((self: Ray) => self.initial, Interface.any.rays); + } + }, + { + combo: "d", global: true, label: "", onKeyDown: () => { + Interface.any.selection = Interface.any.selection.move((self: Ray) => self.terminal, Interface.any.rays); + } + }, + { + combo: "w", global: true, label: "", onKeyDown: () => { + Interface.any.selection = Interface.any.selection.move((self: Ray) => self.self, Interface.any.rays); + } + }, + { + combo: "/", global: true, label: "", onKeyDown: () => { + console.log('ref', Interface.any.selection) + console.log('ref.self', Interface.any.selection.self) + } + }, + { + combo: "f3", global: true, label: "Show stats Panel", onKeyDown: (e) => { + e.preventDefault(); + Interface.any.stats = !Interface.any.stats; + } + }, + ] as HotkeyConfig[] + }) + })); + + const { selection, controls, rays } = Interface.any; + const { hotkeys } = controls.any; + + hotkeyConfig.set(...hotkeys); + + const render: { [TKey in keyof InterfaceOptions]: (ray: Ray) => InterfaceOptions[TKey] } = { + position: (ray: Ray) => ray.self.any.position ?? (ray.is_none() ? [0, 400, 0] : [0, 0, 0]), + rotation: (ray: Ray) => ray.self.any.rotation ?? [0, 0, 0], + scale: (ray: Ray): number => ray.self.any.scale ?? (ray.is_none() ? 1.5 : 1.5), + color: (ray: Ray): string => ray.self.any.color ?? (ray.is_none() ? 'red' : 'orange'), + } + + const options = (ray: Ray): Required => _.mapValues(render, (func: any) => func(ray)) as Required; + + const Render = ({ ray }: { ray: Ray }) => { + const initial: Required = options(ray.self.initial.as_reference()); + const vertex: Required = options(ray); + const terminal: Required = options(ray.self.terminal.as_reference()); + + switch (ray.type) { + case RayType.REFERENCE: + return + case RayType.INITIAL: { + return <> + + <_Continuation {...vertex} /> + + } + case RayType.TERMINAL: { + return <> + + <_Continuation {...vertex} /> + + } + case RayType.VERTEX: { + return <_Vertex {...vertex} /> + } + } + } + + return <> + {Interface.any.stats ? : <>} + + + + {/*{Interface.any.rays.map((ray: Ray) => )}*/} + {Interface.any.rays.map((ray: Ray) => )} + +} + +const StatsPanels = () => { + const [_, forceUpdate] = useReducer((x) => !x, false); + + const parent = useRef(document.createElement('div')); + + useEffect(() => { + document.body.appendChild(parent.current); + + for (let i = 0; i < parent.current.children.length; i++) { + (parent.current.children[i] as any).style.cssText = `position: fixed; top: 0px; left: ${(i !== 0 ? 190 : 0) + 80 * i}px; cursor: pointer; opacity: 0.9; z-index: 10000;`; + } + + if (parent.current.children.length < 3) + forceUpdate(); + }, [_]); + + return <> + + {/**/} + + + +} + +const DebugCanvas = ( + { + listeners = [], + }: { + listeners?: IEventListener[], + } +) => { + const listener: IEventListener = { + + } + + return
+
+ + + +
+} + +export const DebugExplorer = ( + { + listeners = [], + }: { + listeners?: IEventListener[], + } +) => { + + const listener: IEventListener = {} + + return +} diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index a128617..f22aa92 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1,4 +1,5 @@ import {Arbitrary, Ray} from "../../explorer/Ray"; +import {NotImplementedError} from "../../explorer/errors/errors"; /** * An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Rays. @@ -89,7 +90,7 @@ export namespace Chyp { } dpo = (match: Match): Ray => { - + throw new NotImplementedError(); } } diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 9097b15..6e96c8f 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -28,7 +28,6 @@ const Interface = () => { // TODO: Direct call to rerender on change, now there's lag - const [Chyp] = useState(Ray.vertex().o({ selection: Ray .vertex().o({ position: [0, 0, 0], scale, color: 'orange' }) diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts index 23226b4..387a61a 100644 --- a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts +++ b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts @@ -1,1587 +1,1587 @@ -import {JS, Ray} from "../../explorer/Ray"; -import {NotImplementedError} from "../../explorer/errors/errors"; - -/** - * - The .copy()'s are implemented on Ray. - * - * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. - * - * TODO: Probably want all these types at runtime, to display them - * - * TODO: Graph boundary is automatic with this structure? - * - * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? - * - * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. - * - * TODO: Can just move the terminal which holds the oointer to the boundary - * - * TODO: Automatically generate visual examples of all the methods - * - * TODO: Runtime errors as rays - * - * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph - */ -/** - * TODO: These coordinates used for inferences? - * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" - */ - -export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; - -export const Color = (t1: Ray = str('')): Ray => { throw new NotImplementedError() }; - -export class ValueError extends Error {} - -/** - * Non-default vertex types are identified by a string label - * - * str() | None() - No overloading in TypeScript ;( - */ -export const VType = JS.Iterable([str, None]); - -/** - * Used for debugging (the matcher) - */ -const DEBUG = true; // TODO; Generalize -const log = (s: string) => { - if (!DEBUG) - return; - - console.log(s); -} - -/** - * Data associated with a single vertex. - */ -export class VData extends Ray { - // The vertex type. - vtype = this.property('vtype', None); - - // The register size (number of bundled parallel wires) of the vertex. - size = this.count; // Implemented on Ray.count - - // TODO: These infers will probably be removed? - // Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). - infer_type = this.property('infer_type', bool(False)) - // Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). - infer_size = this.property('infer_size', bool(False)) - - // x-coordinate at which to draw the vertex. - x = this.property('y', int(0)) - // y-coordinate at which to draw the vertex. - y = this.property('y', int(0)) - - highlight = this.property('highlight', bool(False)) - value = this.property('value') - - /** - * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. - */ - get in_indices(): Ray { return this.initial } // - get out_indices(): Ray { throw new NotImplementedError(); } - - is_input = (): Ray => this.in_indices.count.as_int() > 0; - is_output = (): Ray => this.out_indices.count.as_int() > 0; - is_boundary = (): Ray => this.is_input() || this.is_output(); - - // TODO: Probably generalizable - - /** - * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. - * - * TODO; particular sort of composing - */ - merge = (other: VData): Ray => { - throw new NotImplementedError(); - } - - fresh = (): VData => { - // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. - - // vtype=vd.vtype, size=vd.size, - // x=vd.x, y=vd.y, value=vd.value - - } - - // TODO: Shouldn't be here, this should be implemented on Ray if it's general enough - get domain(): Ray { return JS.Iterable([this.vtype, this.size]) }; - -} - -export class EData extends Ray { - - fg = this.property('bg', Color()); - bg = this.property('bg', Color()); - x = this.property('y', int(0)); - // y-coordinate at which to draw the vertex. - y = this.property('y', int(0)); - highlight = this.property('highlight', bool(False)) - hyper = this.property('value', bool(True)) - value = this.property('value') - - __repr__ = (): Ray => { throw new NotImplementedError(); - // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' - } - - // TODO: More stuff to relate it to the screen that shouldnt be here. - /** - * Return how many width 'units' this box needs to display nicely. - * - * This uses a simple rule: - * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. - * - Otherwise draw as a larger (size 2) box. - */ - box_size = (): Ray => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); - - domain = (): Ray => this.source.cast().domain; - codomain = (): Ray => this.target.cast().domain; - - toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL -} - -/** - * A hypergraph with boundaries. - * - * This is the main data structure used by Chyp. It represents a directed - * hypergraph (which we call simply a "graph") as two dictionaries for - * vertices and (hyper)edges, respectively. Each vertex is associated with a - * `VData` object and edge edge with an `EData` object, which stores - * information about adjacency, position, label, etc. - * - * The particular flavor of hypergraphs we use associate to each hyperedge a - * list of source vertices and a list of target vertices. The hypergraph - * itself also has a list of input vertices and a list of output vertices, - * which are used for sequential composition and rewriting. - */ -export class Graph extends Ray { - - get vindex(): Ray { return this.vdata.index.max(0); } - get eindex(): Ray { return this.edata.index.max(0); } - - // Mapping from integer identifiers of each vertex to its data. - vdata = this.property('vertices'); - // Mapping from integer identifiers of each hyperedge to its data. - edata = this.property('edges'); - - // TODO .keys - vertices = this.property('vertices'); - edges = this.property('edges'); - - /** - * Return the domain of the graph. - * - * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. - */ - // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. - get domain(): Ray { return this.inputs.cast().domain; }; - - /** - * Return the domain of the graph. - * - * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. - */ - get codomain(): Ray { return this.outputs.cast().domain; }; - - vertex_data = (v = int): VData => this.vertices().at(v).cast(); - edge_data = (e = int): EData => this.edges().at(e).cast(); - - // TODO: Shouldnt be here - ___next_index = (name = int(-1), index: Ray): Ray => { - // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) - const current = name === -1 ? index : Math.max(name, index); - return current + 1; - } - - /** - * Add a new vertex to the graph. - * - * @param name The value carried by this vertex (currently unused). - * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. - * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). - */ - add_vertex = (name = int(-1), vertex: VData): VData => { - this.vindex = this.___next_index(name, this.vindex); - - this.vdata[this.vindex - 1] = vertex; - return vertex; - } - - /** - * Add a new hyperedge to the graph. - * - * @param s - * @param t - */ - add_edge = (name = int(-1), edge: EData): EData => { - this.eindex = this.___next_index(name, this.eindex); - - this.edata[this.eindex - 1] = edge; - - // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) - // for v in s: - // self.vdata[v].out_edges.add(e) - // for v in t: - // self.vdata[v].in_edges.add(e) - - return edge; - } - // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. - - /** - * Remove a vertex from the graph. - * - * This removes a single vertex. - * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. - * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. - * - * @param v - * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. - */ - remove_vertex = (v = int, strict: boolean = false): Ray => { - // TODO: destroy any reference of it (could just do this lazy) - // TODO: as delegation - - if (strict) { - if (this.vertex_data(v).in_edges.count.as_int() > 0 || this.vertex_data(v).out_edges > 0) { - throw new ValueError('Attempting to remove vertex with adjacent' - + 'edges while strict == True.'); - } - - if (this.inputs.includes(v) || this.outputs.includes(v)) { - throw new ValueError('Attempting to remove boundary vertex while' - + 'strict == True.'); - - }// TODO CAN BE SIMPLIFIED - } - - // in/out edges from all vertices - delete this.vdata[v]; - } - - /** - * Remove an edge from the graph. - * - * @param e Integer identifier of the edge to remove. - */ - remove_edge = (e = int): Ray => { - // TODO: destroy any reference of it (could just do this lazy) - // in/out edges from all vertices - delete this.edata[e]; - } - - // TODO: Can these be overlaoded in properties using -=, += in TS? - - - - - // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. - - - - // set function: - // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs - // inputs =, outputs = - // for the add functions: // TODO: Perhaps splat - // also for add // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) - - - /** - * Return vertices that lie on a directed path from any of `vs`. - * // TODO: Just traverse the rays, deduplicate using the index - */ - successors = (ray: Ray): Ray => ray.next; - - /** - * Split a vertex into copies for each input, output, and tentacle. - * - * This is used for computing pushout complements of rules that aren't left-linear. - * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). - * - * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. - * - * @param v Integer identifier of vertex to be exploded. - */ - explode_vertex = (v = int): Ray => { - const vertex = this.vertex_data(v); - - // TODO; This just seems like another copy which minor changes - - const next_inputs = empty(); - const next_outputs = empty(); - - const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process - vertex: VData, - boundary: (vertex: VData) => Ray, - next_boundary: Ray - ) => { - // TODO: It's just a duplicated process for vertex/edge since their definition is separataed - - // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. - // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs]) - // TODO: Basically a copy, and replace this one vertex - - // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. - boundary(vertex).all(e => { - const edge: EData = e.cast(); - - edge.t = edge.t - .map(target => { - if (target === v) - return target; - - const fresh_vertex = vertex.fresh(); - next_boundary.add(this.add_vertex(fresh_vertex)) - boundary(fresh_vertex).add(edge); - }) - }); - - } - - // TODO: It's always just duplicated for both ends, - __temp(vertex, (vertex) => vertex.in_edges, next_inputs); - __temp(vertex, (vertex) => vertex.out_edges, next_outputs); - - // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. - vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal - vertex.out_edges.clear(); - - // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). - this.remove_vertex(vertex, true); - - return [next_inputs, next_outputs]; - } - - - /** - * Insert a new identity hyperedge after the given vertex. - * - * A new vertex is also created, which replaces the original vertex as the source of any edges in graph as well as any occurrences of the original vertex in the graph outputs. - * - * @param reverse - * - If `False`, the original vertex becomes the source of the ew identity hyperedge while the new vertex becomes the target. - * - If `True`, the source and target of the new identity are flipped. This can be used to break directed cycles, by neffectively introducing a cap and cup. - */ - insert_id_after = (v = int, reverse = bool(False)): Ray => { - const vertex = this.vertex_data(v); - - // Create a new vertex with the same vtype and size - // //TODO ; Which is this .fresh - const new_vertex = vertex.fresh(); - new_vertex.x += 3; - // The new vertex is highlighted whenever the orignal vertex is. - new_vertex.highlight = vertex.highlight; // TODO: This not done by .fresh? - - /** - * //TODO: BEcause it's inserted after, set the output (generalize to just moving the reference to the terminal. - * # Replace any occurences of the original vertex in the graph outputs - * # with the new vertex. - * self.set_outputs([x if x != v else w for x in self.outputs()]) - */ - - // Where the original vertex is the source of a hyperedge, replace it with the new vertex and register this change with the data instance of each vertex - // TODO syncs the out_edges fields, wd.out_edges.add(e) vd.out_edges.clear() - // TODO replace out_edges.source to new_vertex again - - // Assign the orignal and new vertex as source or target of the new identity edge, based on the `reverse` argument. - // TODO: Sets reverse just flipping around the initial/terminal.. - // TODO: s, t = ([v], [w]) if not reverse else ([w], [v]) - - // Create the new identity edge. - const edge = this.add_edge() // s, t, 'id', vd.x + 1.5, vd.y) - edge.hightlight = vertex.highlight; // The new edge is highlighted whenever the original vertex is. - - return edge; - } - - /** - * Take the monoidal product of this graph in-place with another. - * - * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. - * - * @param other - * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. - */ - tensor = (other: Graph, layout: boolean = true): Ray => { - - const a = this; - const b = other; - - const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] - - tensor.initial.any.y -= - tensor.initial.any.y.max(); // max_self - - tensor.terminal.any.y -= - (layout ? tensor.terminal.any.y.min() : 0) + 1; // min_other TODO: Why + 1 ? - - /** - * # self.set_inputs(self.inputs + [vmap[v] for v in other.inputs]) - * # self.set_outputs(self.outputs + [vmap[v] for v in other.outputs]) - * - * # Add the inputs and outputs of the other graph to this one. - * self.add_inputs([vmap[v] for v in other.inputs]) - * self.add_outputs([vmap[v] for v in other.outputs]) - */ - // TODO: Add equivalence/reference on the inputs/output extremes. - } - - /** - * Sequentially compose this graph in-place with another. - * - * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. - */ - compose = (other: Graph): Ray => { - // TODO Just matching outputs and inputs.. - - // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" - - // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs - - /** - * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. - */ - - // Compute the max x-coordinate of the edges and vertices in this graph. - - // TODO: Again, recursively going through everything defined on the initial side (outputs) - // Shift all vertices and edges of this graph below the x-axis. - compose.initial.any.x -= - compose.initial.any.x.max(); // max_self - - // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] - compose.terminal.any.x -= - compose.terminal.any.x.min(); // min_other - - // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. - /** - * plug1 = self.outputs - * plug2 = [vmap[v] for v in other.inputs] - * - * if len(plug1) != len(plug2): - * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' - * + f'outputs into one with {len(plug2)} inputs') - * - * self.set_outputs([vmap[v] for v in other.outputs]) - */ - - // [outputs to inputs] - // Go through pairs of vertices from each plug - compose.zip().all(([input, output]) => { - /** - * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. - */ - - // TODO: does this ever happen??? - // while p1 in quotient: - // p1 = quotient[p1] - // while p2 in quotient: - // p2 = quotient[p2] - - - // TODO, Again the same equivalence check for loops etc.. - { - // If the resulting p1 and p2 are not the same vertex, merge them. - if (input === output) - return; - - // TODO; DO this on the vertices; - // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) - - // If both vertices have flexible types that are not equal, raise an error due to ambiguity. - // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. - - - // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. - - ['vtype', 'size'].forEach(structure => { - const infer = `infer_${structure}`; - - if (input[infer] && output[infer] && input[structure] !== output[structure]) { - throw GraphError(`Ambiguous vertex ${structure} during composition.`) - - } else if (input[infer]) { - // Otherwise, if one vertex has a flexible type, ensure the vertex types match. - // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it - // TODO: Again both sides same thing.. - input[structure] = output[structure]; // TODO: Generalized structure - input[infer] = false; - } else if (output.infer_type) { - output[structure] = input[structure]; - output[infer] = false; - } - }); - - input.merge(output); - // # Register than p2 has been merged into p1. - // quotient[p2] = p1 - } - }); - } - - /** - * Return the tensor product of this graph with another. - * - * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them - */ - __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); - - /** - * Return the composition of the current graph with `other`. - * - * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. - * @param other - */ - __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); - - /** - * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer - */ - ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { - const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. - something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? - return a_copy; // Could generalize to either end - } - - /** - * Set the `highlight` flag for a set of vertices and edges. - * - * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. - * - * @param vertices A set of vertices to highlight. - * @param edges A set of edges to highlight. - */ - highlight = (vertices = set(int), edges = set(int)): Ray => { - // TODO Again, these could be merged - this.vdata - .filter(vertex => vertices.includes(vertex)) - .all(vertex => vertex.cast().highlight = bool(true)); - this.edata - .filter(edge => edges.includes(edge)) - .all(edge => edge.cast().highlight = bool(true)); - - } - - /** - * Clear the `highlight` flag for all vertices/edges. - * - * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. - */ - unhighlight = (): Ray => { - // TODO: These could be merged - this.vdata.highlight = false; - this.edata.highlight = false; - } - - /** - * Return matches of domain into codomain. - */ - match = (other: Graph, convex: boolean = true): Matches => new Matches(this, other, convex); - - /** - * Return an isomorphism between graphs g and h if found, otherwise `None`. - * - * If found, the isomorphism is returned as a :py:class:`Matches` instance, whose vertex and edge maps are bijections. - */ - find_iso = (other: Graph): Match => { // TODO | NONE - - // TODO: Again, more equivalence checks - // First, check the domains and codomains are equal between the two graphs. - if (this.domain !== other.domain || this.codomain !== other.codomain) - return None; //TODO - - // Try to find an initial match mapping one of the boundary vertices of the domain graph to the corresponding boundary vertex (the vertex in the same input/output location) of the codomain graph. If no initial match is found, return `None`. - const initial_match = new Match(this, other); - - const ___temp = (func: (ray: Graph) => Ray) => { - ([func(this), func(other)] as Ray).zip(([initial, terminal]) => { - if (!initial_match.try_add_vertex(initial, terminal)) - return None; //TODO, DOESNT ACTUALLY RETURN THE FUNCTION HERE. Wait till matcher is abstracted to fix this - }); - } - - ___temp(ray => ray.inputs); - ___temp(ray => ray.outputs); // TODO: See again, the same pattern over and over again, same on both sides. - - // If an initial match is found, try to find a total and surjective match of the domain graph into the codomain graph. - - return new Matches(this, other, initial_match, false) - .filter(match => match.is_surjective()); // TODO; With this filter it should allow you to keep looking - - // TODO::: Automatic?? - // If a total surjective match is not found, return `None`. - return None; - } -} - -export class Chyp extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - - /** - * Load a .chyp graph file from the given path. - */ - load_graph = (path = str) => { - // TODO: From localStorage for now? - // with open(path) as f: - // g = graph_from_json(f.read()) - } - - /** - * Return a graph corresponding to the identity map. - * - * This graph has a single vertex which is both an input and an output. - */ - identity = (vertex: VData): Graph => { - const graph = new Graph(); - - vertex.x = 0; // TODO automatic>? - vertex.y = 0; - graph.add_vertex(int(-1), vertex); - // TODO synce input/output automatically? - // g.set_inputs([v]) - // g.set_outputs([v]) - - return graph; - } - - - ___map_domain = (domain: Ray, _default: VData): Ray => { - return domain.map(([vtype, size], i) => { - const vertex: VData = _default.copy().cast(); - // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere - vertex.x = -1.5; - vertex.y = i - (i-1) / 2; - - return vertex; - }) - } - - /** - * Return a graph with one hyperedge and given domain and codomain. - * - * @param _default - * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. - * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. - */ - gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { - const graph = new Graph(); - - const inputs = this.___map_domain(domain, _default) - .map(vertex => graph.add_vertex(vertex)); - const outputs = this.___map_domain(codomain, _default) - .map(vertex => graph.add_vertex(vertex)); - - // TODO This is probably automatic at some point, remove - const edge = new EData(); - edge.s = inputs; - edge.t = outputs; - graph.add_edge(int(-1), edge); - // g.set_inputs(inputs) - // g.set_outputs(outputs) - - return graph; - } - - /** - * Return a graph corresponding to the given permutation. - * - * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. - * - * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. - * - * @param p A permutation given as an n-element list of integers from 0 to n-1. - * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. - */ - perm = (p = list(int), domain: Ray, _default: VData) => { - - const graph = new Graph(); - const num_wires = p.count.as_int(); - - if (num_wires !== domain.count.as_int()) - throw new GraphError(`Domain ${domain} does not match length of permutation.`) - - // TODO use ___map_domain - const inputs = domain.map(([vtype, size], i) => { - const vertex: VData = _default.copy().cast(); - // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere - vertex.x = 0; - vertex.y = i - (num_wires - 1) / 2; - - return vertex; - }) - .map(vertex => graph.add_vertex(vertex)); - // const outputs = num_wires.range(i => [inputs[p[i]]) - - // TODO Should be automatic - // g.set_inputs(inputs) - // g.set_outputs(outputs) - return graph; - } - - graph_from_json = (json_string = str): Graph => { - const json = JSON.parse(json_string().as_string()); // TODO - - const graph = new Graph(); - - // TODO: Don't do this so naively - // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), - // y=float(vd["y"] if "y" in vd else 0.0), - // value=vd["value"] if "value" in vd else "", - // name=int(v)) - // for e, ed in j["edges"].items(): - // g.add_edge(s=[int(v) for v in ed["s"]], - // t=[int(v) for v in ed["t"]], - // value=ed["value"] if "value" in ed else "", - // x=float(ed["x"]) if "x" in ed else 0.0, - // y=float(ed["y"]) if "y" in ed else 0.0, - // hyper=bool(ed["hyper"]) if "hyper" in ed else True, - // name=int(e)) - // - // g.set_inputs([int(v) for v in j["inputs"]]) - // g.set_outputs([int(v) for v in j["outputs"]]) - // json.vertices.forEach(((vertex, i) => graph.add_vertex( - // i, - // new VData() - // )); - - return graph; - } - - /** - * # def wide_id() -> Graph: - * # return gen("id", 1, 1) - * - * # def id_perm(p: List[int]) -> Graph: - * # g = Graph() - * # size = len(p) - * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] - * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] - * - * # for i in range(size): - * # y = i - (size-1)/2 - * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) - * - * # g.set_inputs(inputs) - * # g.set_outputs(outputs) - * - * # return g - */ - - /** - * Return a graph corresponding to a vertex size redistribution. - * - * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. - * - * More generally, a conversion can be done between different lists of sizes, for some vertex type. - * - * @param domain A list of pairs (vertex type, register size) corresponding to each input vertex. - * @param codomain A list of pairs (vertex type, register size) corresponding to each output vertex. - */ - redistributer = (domain = list, codomain = list) => { - /** - * vtypes = set(vtype for vtype, _ in domain) - * vtypes.update(vtype for vtype, _ in codomain) - * if len(vtypes) > 1: - * raise GraphError('Size conversion cannot mix vertex types.') - * - * # Raise error if size conservation is violated - * domain_size = sum(size for _, size in domain) - * codomain_size = sum(size for _, size in codomain) - * if domain_size != codomain_size: - * raise GraphError(f'Sum of domain sizes ({domain_size}) does not equal' - * + f'sum of codomain sizes ({codomain_size}).') - * - * return gen('_redistributer', domain, codomain) - */ - - } - - /** - * Some more delegations here - */ - match_graph = (domain: Graph, codomain: Graph, convex: boolean = true): Matches => domain.match(codomain, convex); - match_rule = (rule: Rule, codomain: Graph, convex: boolean = true): Matches => rule.match(codomain, convex); - find_iso = (domain: Graph, codomain: Graph): Match => domain.find_iso(codomain); -} - -export class CodeView extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - popup_visible = (): Ray => { throw new NotImplementedError(); } - set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } - ident_at_cursor = (): Ray => { throw new NotImplementedError(); } - insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } - keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } - set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } - add_line_below = (text = str): Ray => { throw new NotImplementedError(); } -} - -export class CodeCompletionModel extends Ray { - __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } - set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } - data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } - rowCount = (): Ray => { throw new NotImplementedError(); } -} - -export class ChypDocument extends Ray { - __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } - confirm_close = (): Ray => { throw new NotImplementedError(); } - add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } - open = (file_name = str): Ray => { throw new NotImplementedError(); } - save = (): Ray => { throw new NotImplementedError(); } - save_as = (): Ray => { throw new NotImplementedError(); } -} - -export class Editor extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - title = (): Ray => { throw new NotImplementedError(); } - reset_state = (): Ray => { throw new NotImplementedError(); } - invalidate_text = (): Ray => { throw new NotImplementedError(); } - next_part = (): Ray => { throw new NotImplementedError(); } - jump_to_error = (): Ray => { throw new NotImplementedError(); } - show_errors = (): Ray => { throw new NotImplementedError(); } - show_at_cursor = (): Ray => { throw new NotImplementedError(); } - next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } - repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } - update_state = (): Ray => { throw new NotImplementedError(); } - import_at_cursor = (): Ray => { throw new NotImplementedError(); } -} - -export class CheckThread extends Ray { - __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } - run = (): Ray => { throw new NotImplementedError(); } -} - -export class ErrorListModel extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } - data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } - headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } - index = (row = int, column = int): Ray => { throw new NotImplementedError(); } - columnCount = (): Ray => { throw new NotImplementedError(); } - rowCount = (): Ray => { throw new NotImplementedError(); } - parent = (): Ray => { throw new NotImplementedError(); } -} - -export class EItem extends Ray { - __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } - paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } -} - -export class VItem extends Ray { - __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } - refresh = (): Ray => { throw new NotImplementedError(); } -} - -export class TItem extends Ray { - __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } - refresh = (): Ray => { throw new NotImplementedError(); } -} - -export class GraphScene extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } - add_items = (): Ray => { throw new NotImplementedError(); } - mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } - mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } - mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } -} - -export class GraphView extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } -} - -export class ChypHighlighter extends Ray { - __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } - set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } - highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } -} - -export class MainWindow extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - remove_empty_editor = (): Ray => { throw new NotImplementedError(); } - update_file_name = (): Ray => { throw new NotImplementedError(); } - tab_changed = (i = int): Ray => { throw new NotImplementedError(); } - update_themes = (): Ray => { throw new NotImplementedError(); } - recent_files = (): Ray => { throw new NotImplementedError(); } - update_recent_files = (): Ray => { throw new NotImplementedError(); } - add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } - close_tab = (): Ray => { throw new NotImplementedError(); } - new = (): Ray => { throw new NotImplementedError(); } - open = (): Ray => { throw new NotImplementedError(); } - save = (): Ray => { throw new NotImplementedError(); } - save_as = (): Ray => { throw new NotImplementedError(); } - undo = (): Ray => { throw new NotImplementedError(); } - redo = (): Ray => { throw new NotImplementedError(); } - show_errors = (): Ray => { throw new NotImplementedError(); } - add_rewrite_step = (): Ray => { throw new NotImplementedError(); } - repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } - next_rewrite = (): Ray => { throw new NotImplementedError(); } - next_part = (): Ray => { throw new NotImplementedError(); } - previous_part = (): Ray => { throw new NotImplementedError(); } - next_tab = (): Ray => { throw new NotImplementedError(); } - previous_tab = (): Ray => { throw new NotImplementedError(); } - goto_import = (): Ray => { throw new NotImplementedError(); } - closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } - build_menu = (): Ray => { throw new NotImplementedError(); } -} - -// TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? -export class Match extends Ray { - - get vertex_map(): Ray { throw new NotImplementedError(); } - get vertex_image(): Ray { throw new NotImplementedError(); } - get edge_map(): Ray { throw new NotImplementedError(); } - get edge_image(): Ray { throw new NotImplementedError(); } - - __str__ = (): Ray => { - // (f'\tVertex map: {str(self.vertex_map)}' - // + f'\n\tEdge map: {str(self.edge_map)}') - // TODO - throw new NotImplementedError(); } - - // Implemented on Ray - // TODO; doesnt copy the graphs at domain/codomain - // copy = (): Ray => { throw new NotImplementedError(); } - - /** - * Try to map `domain_vertex` to `codomain_vertex`. - * - * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. - * - * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. - */ - try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { - - // If the vertex is already mapped, only check the new mapping is consistent with the current match. - if (this.vertex_map.includes(domain_vertex)) { - log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) - return this.vertex_map[domain_vertex] === codomain_vertex; - } - - // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. - // TODO: This should all be redundant, probably removed ... - - // Ensure the mapping preserves vertex type. - if (domain_vertex.vtype !== codomain_vertex.vtype) { - log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); - - return bool(False); - } - - // Ensure the mapping preserves vertex size. - if (domain_vertex.size !== codomain_vertex.size) { - log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) - return bool(False); - } - - // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. - if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { - log('Vertex failed: codomain vertex is boundary but domain vertex is not.') - return bool(False); - } - - // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. - if (this.vertex_image.includes(codomain_vertex)) { - // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. - if (!domain_vertex.is_boundary()) { - log('Vertex failed: non-injective on interior vertex.') - return bool(False); - } - - // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. - if (this.vertex_image.any(([mapped_vertex, image_vertex]) => - image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! - )) { - log('Vertex failed: non-injective on interior vertex.') - return bool(False); - } - - return bool(False); - } - - // If a new and consistent map is found, add it to the vertex map of this match. - this.vertex_map[domain_vertex] = codomain_vertex - this.vertex_image.add(codomain_vertex) - - // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. - - if (!domain_vertex.is_boundary()) { - if (domain_vertex.in_edges.count.as_int() !== codomain_vertex.in_edges.count.as_int()) { - log('Vertex failed: in_edges cannot satisfy gluing conditions.') - return bool(False) - } - if (domain_vertex.out_edges.count.as_int() !== codomain_vertex.out_edges.count.as_int()) { - log('Vertex failed: in_edges cannot satisfy gluing conditions.') - return bool(False) - } - } - - // If a new consistent map is added that satisfies the gluing conditions, we are successful. - log('Vertex success.') - return bool(True); - } - - /** - * Try to map `domain_edge` to `codomain_edge`. - * - * This must satisfy certain conditions, such as being injective and having consistency with the vertex map. - * - * @param domain_edge - * @param codomain_edge - * - * `True` if a consistent match is found mapping `domain_edge` to `codomain_edge`, otherwise `False`. - */ - try_add_edge = (initial: EData, terminal: EData): Ray => { - log(`Trying to add edge ${initial} -> ${terminal} to match:`); - log(this.toString()); - - // TODO: Again an equivalence - // Check the values of the domain and codomain edges match. - if (initial.value !== terminal.value) { - log(`Edge failed: values ${initial.value} != ${terminal.value}`) - return false; - } - - // The edge map must be injective. - if (this.edge_image.includes(terminal)) { - console.log('Edge failed: the map would become non-injective.'); - return false; - } - - // If the values match and the codomain edge has not already been mapped to, map domain edge to codomain edge. - this.edge_map[initial] = terminal; - this.edge_image.add(terminal); - - // Domain sources must match codomain sources and domain targets must match codomain targets. - - // TODO: Again more equivalences, just to log - debug mode - { - // initial = preimg - // terminal = image - - // Domain sources must match codomain sources and domain targets must match codomain targets. - if (initial.domain !== terminal.domain) { - log(`Edge domain ${initial.domain} does not match image domain ${terminal.domain}.`); - } - - // TODO, again both sides - if (initial.codomain !== terminal.codomain) { - log(`Edge codomain ${initial.codomain} does not match image codomain ${terminal.codomain}.`); - } - } - - // TODO: This too probably general pattern to extract - // Check a vertex map consistent with this edge pairing exists. - // TODO: + here is just concat, so that zip can easily match it - ([initial.source + initial.target, terminal.source + terminal.target] as Ray).zip(([initial_vertex, terminal_vertex]) => { - // Each vertex that is already mapped needs to be consistent. - // TODO: More equivlaency, could be on the vertecies themselves - if (this.vertex_map.includes(initial_vertex) && this.vertex_image[initial_vertex] !== terminal_vertex) { - log('Edge failed: inconsistent with previously mapped vertex.'); - return false; // TODO: NOT RETURNING AGAIN - } - - // Otherwise, a consistent match must be found vertex for unmapped source and target vertices. - - if (!this.try_add_vertex(initial_vertex, terminal_vertex)) { - log('Edge failed: couldn\'t add a source or target vertex.'); - return false; - } - }); - - log('Edge success.'); - return true; - } - - /** - * Return whether all adjacent edges of a domain vertex are mapped. - */ - domain_neighbourhood_mapped = (vertex: VData): Ray => - ([vertex.in_edges + vertex.out_edges] as Ray).all(edge => this.edge_map.includes(edge)); - - /** - * # def cod_nhd_mapped(self, cod_v: int): - * # """Returns True if nhd(cod_v) is the range of emap""" - * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and - * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) - */ - - /** - * Try to extend the match by mapping all scalars (i.e. 0 -> 0 edges). - * - * Note that any matchings of scalars will yield isomorphic results under rewriting, so we don't return a list of all the possible matchings. - * - * Returns: `True` if all scalars in the domain are mapped injectively to scalars in the codomain, otherwise `False`. - */ - map_scalars = (): Ray => { - //TODO WHAT'S A SCALAR HERE? - // TODO: Again same pattern for (co)domain - flipped, two dimensional - const ___scalars = (domain: Graph, reverse: boolean) => { - const is = (ray: Ray) => reverse ? ray.count !== 0 : ray.count === 0; // TODO: Should be easier to just .not this - - return domain.edges - .filter((edge: EData) => this.is(edge.source) && this.is(edge.target)); - } - - const terminal = ___scalars(this.codomain, false); - const initial = ___scalars(this.domain, true); - - // Greedily try to map scalar edges in the domain to scalar edges in the codomain with the same value. - initial.all((initial_edge: EData) => { - // TODO: Put initial/terminal edge on a ray and then apply funcitons - - log(`Trying to map scalar edge ${initial_edge}`) - - let found_match = false; - - // TODO .enumerate?? - terminal.all(([i, terminal_edge]) => { - if (initial_edge.value !== terminal_edge.value) // ANother equiv - return; // TODO continue; - - // Map the domain scalar to the first codomain scalar available with the same value. - this.edge_map[initial_edge] = terminal_edge; - this.edge_image.add(terminal_edge); // TODO: Again map/image is just initial/terminal.. same as domain/codomain,, - - found_match = true; - - // Since the edge map must be injective, if a scalar in the codomain is mapped to, remove it from the list of candidates for future domain scalars to be mapped to. - terminal.pop(i); // TODO: ??? - - log(`Successfully mapped scalar ${initial_edge} -> ${terminal_edge}`) - - // TODO: BREAK ; any?? - }); - - if (!found_match) { - log(`Match failed: could not map scalar edge ${initial_edge}.`) - return false; // TODO DOESNT RETURN - } - }); - - return true; - } - - - // TODO: IF MORE JUST ADDS MORE MATCHES IN THIS DIRECTION, THAT SHOULD BE AUTOMATIC ON .match ... ? - /** - * Return any matches extending `self` by a single vertex or edge. - */ - more = (): Ray => { - // First, try to add an edge adjacent to any domain vertices that have already been matched. - this.vertex_map - // If all the edges adjacent to the current vertex have already been matched, continue. TODO: Could just be on the .vertex - .filter(initial_vertex => this.domain_neighbourhood_mapped(initial_vertex)) - .all((initial_vertex: VData) => { - // TODO: AS ZIp or something - const terminal_vertex = this.vertex_map[initial_vertex]; - - const ___test = (boundary: (ray: Graph) => Ray): Ray => { - // Try to extend the match by mapping an adjacent source edge. - boundary(this.domain) // TODO: AGAIN SAME THING - // If the edge has already been matched, continue. - .filter(edge => !this.edge_map.includes(edge)) - .all((initial_edge: EData) => { - - // Otherwise, try to map this edge into the codomain graph. - return boundary(this.codomain).map(terminal_edge => { - const potential_new_match = this.copy(); - - // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. - if (potential_new_match.try_add_edge(initial_edge, terminal_edge)) - return potential_new_match; - - return NONE;//todo - }); // TODO REMOVE NON-ADDED_ONES, doesnt actually reutn either - }) - - } - - ___test(ray => ray.in_edges); - ___test(ray => ray.out_edges); - - }); - - // If all domain edges adjacent to matched domain vertices have already been matched, try to match an unmatched domain vertex. - this.domain.vertices - // If the vertex has already been matched into the codomain graph, continue. (Note we have looked at the edge-neighbourhood of these vertices above) - .filter(initial_vertex => this.vertex_map.includes(initial_vertex)) // TODO: THIS THING IS JUST A COPY, AGAIN FROM THE VERTEX/EDGE DIFFERENTIATION FROM ABOVE - .all(initial_vertex => { - - // Try to map the current domain vertex to any of the codomain vertices, extending the current match with this map when successful. - return this.codomain.vertices.map((terminal_vertex: VData) => { - const potential_new_match = this.copy(); - - // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. - if (potential_new_match.try_add_vertex(initial_edge, terminal_edge)) - return potential_new_match; - - return NONE;//todo - }); // TODO: AGAIN DOESNT RETURN - }) - - return []; - } - - // TODO: Total=surjective on another level of description ??? - ___defuq = (string: 'image' | 'map', domain) => - this[`vertex_${string}`].count === domain.vertices.count - && this[`edge_${string}`].count === domain.edges.count; // TODO: Again vertex/edge pattern, just collapse to one check - - /** - * Return whether all domain vertices and edges have been mapped. - */ - is_total = (): Ray => this.___defuq('map', this.domain); - /** - * Return whether the vertex and edge maps are surjective. - */ - is_surjective = (): Ray => this.___defuq('image', this.codomain); - - /** - * Return whether the vertex and edge maps are injective. - */ - is_injective = (): Ray => { - // Since the edge map is always injective, we only need to check the vertex map is injective. TODO (GENERALIZE) - return this.vertex_map.count === this.vertex_image.count; - } - - /** - * Return whether this match is convex. - * - * A match is convex if: - * - It is injective. - * - Its image in the codomain hypergraph is a convex sub-hypergraph. This means that for any two nodes in the sub-hypergraph and any path between these two nodes, every hyperedge along the path is also in the sub-hypergraph. - * - * TODO: Just no overlap?? - */ - is_convex = (): Ray => { - if (!this.is_injective()) { //TODO: WHY? - return false; - } - - - // Check that the image sub-hypergraph is convex. Get all successors of vertices in the image of the output of the domain graph. - const output_image_successors = this.codomain.successors( - this.domain.outputs - .filter(vertex => this.vertex_map[vertex]) // TODO INCLUDES - ); // TODO, Why search in codomain fromi these, ?? this must be easier - - // Check there is no path from any vertices in the image of the domain outputs to a vertex in the image of the domain inputs. - this.domain.inputs - .filter(vertex => this.vertex_map.includes(vertex) && output_image_successors.includes(this.vertex_map[vertex])) - .any(() => { return false }) // TODO DOESNT ACTUALLY RETURNM - - return true; - } - - /** - * TODO Not implemented;; - * # def cod_nhd_mapped(self, cod_v: int): - * # """Returns True if nhd(cod_v) is the range of emap""" - * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and - * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) - */ -} - -/** - * An iterator over matches of one graph into another. - * - * This class can be used to iterate over total matches of a graph into another, optionally requiring these matches to be convex. - * - * TODO: SUPPORT THIS/?::: - * A class instance works by keeping a stack of partial or total matches. - * When it is iterated over, it pops a match from its match stack if it is - * non-empty, otherwise the iteration is stopped. If a match has been popped, - * the instance returns the match if it is total (and convex if required). - * Otherwise, the instance tries to extend the match and add any extended - * matches to the stack, then continues this process of popping off the match - * stack and extending if possible until a valid match is found and returned. - */ -export class Matches extends Ray { - __init__ = (domain = Graph, codomain = Graph): Ray => { - /** - * TODO - * if initial_match is None: - * initial_match = Match(domain=domain, codomain=codomain) - * self.convex = convex - * - * # Try to map scalars on the initial match. - * if initial_match.map_scalars(): - * self.match_stack = [initial_match] - * # If the scalars could not be mapped, set the match - * # stack to be empty. This means that not suitable matches - * # will be found by this class instance. - * else: - * self.match_stack = [] - */ - throw new NotImplementedError(); } - __iter__ = (): Ray => { throw new NotImplementedError(); } - - /** - * Return the next suitable match found. - * - * A 'suitable' match is one that is total and, if `self.convex == True`, convex. - */ - __next__ = (): Ray => { - // TODO Like expected this, class can probably be dropped this just becomes - - return this.match_stack.dont_check_for_convex_or.is_convex; // TODO: Just generalize these on functions - - /** - * while len(self.match_stack) > 0: - * # Pop the match at the top of the match stack - * m = self.match_stack.pop() - * # If the match is total (and convex if required), return it. - * if m.is_total(): - * match_log("got successful match:\n" + str(m)) - * if self.convex: - * if m.is_convex(): - * match_log("match is convex, returning") - * return m - * else: - * match_log("match is not convex, dropping") - * else: - * return m - * # If the match at the top of the match stack was not total - * # (and convex if required), try to extend the match at the - * # top of the stack and add the results to the match stack. - * else: - * self.match_stack += m.more() - * # If a suitable match was not found, stop the iteration. - * raise StopIteration - */ - } -} - -export class Rule extends Ray { - - get equiv(): Ray { throw new NotImplementedError(); } - - - /** - * Returns True if boundary on lhs embeds injectively - */ - is_left_linear = (): Ray => { - // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading - return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() - .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. - } - - /** - * Do double-pushout rewriting - * - * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. - * @param match - */ - dpo = (match: Match): Ray => { - // if (!this.is_left_linear()) - // throw new NotImplementedError("Only left linear rules are supported for now") - - const rewritten_graph: Graph = match.codomain.copy(); - - // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? - - // Computes the push complement ?? (just the thing we're replacing right?) - // TODO: Removes the match from the copy? - this.lhs.edges.all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); - - const inputs = []; - const outputs = []; - - this.lhs.vertices.all(rule_vertex => { - const match_vertex = match.vertex_map[rule_vertex]; - - if (!this.lhs.is_boundary(rule_vertex)) { - rewritten_graph.remove_vertex(match_vertex); - return; - } - - const rule_input = rule_vertex.in_indices; - const rule_output = rule_vertex.out_indices; - - if (rule_input.count.as_int() === 1 && rule_output === 1) { - const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); - - if (match_input.count.as_int() !== 1 && match_output.count.as_int() !== 1) - throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); - - inputs[rule_vertex] = match_input[0]; - outputs[rule_vertex] = match_output[0]; - } else if (rule_input.count.as_int() > 1 || rule_output.count.as_int() > 1) { - throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); - } - }) - - // Embed Rule.rhs into rewritten_graph - const replacement = new Match(this.rhs, rewritten_graph); - - // TODO: This is probably another of these geeneral patterns, same thing on either ends composed as a single ray., - const input = new Ray(); // [this.lhs.inputs, this.rhs.inputs] - - // first map the inputs, using the matching of the lhs - input.zip().all(([initial, terminal]) => { - match.vertex_map[terminal] = inputs.includes(initial) ? inputs[initial] : match.vertex_map[initial]; - }); - - const output = new Ray(); // [this.lhs.outputs, this.rhs.outputs] - - // next map the outputs. if the same vertex is an input and an output in r.rhs, then merge them in h. - output.zip().all(([initial, terminal]) => { - // TODO: Again, both ends are very similar, there should probably be a direct flip in these, small difference at the end - const temp = outputs.includes(initial) ? outputs[initial] : match.vertex_map[initial]; - - if (match.vertex_map.includes(terminal)) { - rewritten_graph.merge_vertices(match.vertex_map[terminal], temp) - } else { - match.vertex_map[terminal] = temp; - } - }); - - // then map the interior to new, fresh vertices - this.rhs.vertices - .filter(vertex => !vertex.is_boundary()) - .all((vertex: VData) => { - // TODO Again the fresh thing repeated here - just because it's moving between graphs - const new_vertex = rewritten_graph.add_vertex(vertex.fresh()); - - match.vertex_map[vertex] = new_vertex; - match.vertex_image.add(new_vertex); - }); - - // now add the edges from rhs to h and connect them using vmap1 - // TODO: Again this should be the same thing as the vertices - this.rhs.edges. - all((edge: EData) => { - const new_edge = rewritten_graph.add_edge(); - /** - * e1 = h.add_edge([m1.vertex_map[v] for v in ed.s], - * [m1.vertex_map[v] for v in ed.t], - * ed.value, ed.x, ed.y, ed.fg, ed.bg, ed.hyper) - */ - - match.edge_map[edge] = new_edge; - match.edge_image.add(new_edge); - }) - - return replacement; - } - - // TODO: Can probably just match Rule=Graph, and use only one of these methods?? - /** - * Return matches of the left side of `rule` into `graph`. - */ - match = (other: Graph, convex: boolean = true): Matches => new Matches(this.lhs, other, convex); - - /** - * Apply the given rewrite r to at match m and return the first result - * - * This is a convenience wrapper for `dpo` for when the extra rewrite data isn't needed. - */ - rewrite = (match: Match): Ray => this.dpo(match).first.terminal; // .first.codomain - // TODO; Though .first is used here, something like .any is more appropriate in the sense of: Don't care which one first, just something. -} - -export class RewriteState extends Ray { - __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } -} - -export class State extends Ray { - __init__ = (): Ray => { throw new NotImplementedError(); } - part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } - part_at = (pos = int): Ray => { throw new NotImplementedError(); } - var = (items = List(Any)): Ray => { throw new NotImplementedError(); } - module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } - num = (items = List(Any)): Ray => { throw new NotImplementedError(); } - type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } - type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } - id = (items = list(Any)): Ray => { throw new NotImplementedError(); } - id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } - eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } - le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } - perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } - size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } - par = (items = List(Any)): Ray => { throw new NotImplementedError(); } - gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } - color = (items = List(Any)): Ray => { throw new NotImplementedError(); } - import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } - tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } - nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } -} - -export class Tactic extends Ray { - __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } - repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } - error = (message = str): Ray => { throw new NotImplementedError(); } - has_goal = (): Ray => { throw new NotImplementedError(); } - global_rules = (): Ray => { throw new NotImplementedError(); } - lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } - add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } - add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } - __lhs = (target = str): Ray => { throw new NotImplementedError(); } - __rhs = (target = str): Ray => { throw new NotImplementedError(); } - __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } - __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } - rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } - rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } - rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } - rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } - validate_goal = (): Ray => { throw new NotImplementedError(); } - lhs = (): Ray => { throw new NotImplementedError(); } - rhs = (): Ray => { throw new NotImplementedError(); } - lhs_size = (): Ray => { throw new NotImplementedError(); } - rhs_size = (): Ray => { throw new NotImplementedError(); } - highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } - highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } - __reset = (): Ray => { throw new NotImplementedError(); } - next_rhs = (current = str): Ray => { throw new NotImplementedError(); } - run_check = (): Ray => { throw new NotImplementedError(); } - name = (): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } - make_rhs = (): Ray => { throw new NotImplementedError(); } -} - -export class RuleTac extends Ray { - name = (): Ray => { throw new NotImplementedError(); } - make_rhs = (): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } -} - -export class SimpTac extends Ray { - name = (): Ray => { throw new NotImplementedError(); } - __prepare_rules = (): Ray => { throw new NotImplementedError(); } - make_rhs = (): Ray => { throw new NotImplementedError(); } - check = (): Ray => { throw new NotImplementedError(); } -} - +// import {JS, Ray} from "../../explorer/Ray"; +// import {NotImplementedError} from "../../explorer/errors/errors"; +// +// /** +// * - The .copy()'s are implemented on Ray. +// * +// * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. +// * +// * TODO: Probably want all these types at runtime, to display them +// * +// * TODO: Graph boundary is automatic with this structure? +// * +// * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? +// * +// * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. +// * +// * TODO: Can just move the terminal which holds the oointer to the boundary +// * +// * TODO: Automatically generate visual examples of all the methods +// * +// * TODO: Runtime errors as rays +// * +// * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph +// */ +// /** +// * TODO: These coordinates used for inferences? +// * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" +// */ +// +// export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; +// +// export const Color = (t1: Ray = str('')): Ray => { throw new NotImplementedError() }; +// +// export class ValueError extends Error {} +// +// /** +// * Non-default vertex types are identified by a string label +// * +// * str() | None() - No overloading in TypeScript ;( +// */ +// export const VType = JS.Iterable([str, None]); +// +// /** +// * Used for debugging (the matcher) +// */ +// const DEBUG = true; // TODO; Generalize +// const log = (s: string) => { +// if (!DEBUG) +// return; +// +// console.log(s); +// } +// +// /** +// * Data associated with a single vertex. +// */ +// export class VData extends Ray { +// // The vertex type. +// vtype = this.property('vtype', None); +// +// // The register size (number of bundled parallel wires) of the vertex. +// size = this.count; // Implemented on Ray.count +// +// // TODO: These infers will probably be removed? +// // Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). +// infer_type = this.property('infer_type', bool(False)) +// // Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). +// infer_size = this.property('infer_size', bool(False)) +// +// // x-coordinate at which to draw the vertex. +// x = this.property('y', int(0)) +// // y-coordinate at which to draw the vertex. +// y = this.property('y', int(0)) +// +// highlight = this.property('highlight', bool(False)) +// value = this.property('value') +// +// /** +// * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. +// */ +// get in_indices(): Ray { return this.initial } // +// get out_indices(): Ray { throw new NotImplementedError(); } +// +// is_input = (): Ray => this.in_indices.count.as_int() > 0; +// is_output = (): Ray => this.out_indices.count.as_int() > 0; +// is_boundary = (): Ray => this.is_input() || this.is_output(); +// +// // TODO: Probably generalizable +// +// /** +// * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. +// * +// * TODO; particular sort of composing +// */ +// merge = (other: VData): Ray => { +// throw new NotImplementedError(); +// } +// +// fresh = (): VData => { +// // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. +// +// // vtype=vd.vtype, size=vd.size, +// // x=vd.x, y=vd.y, value=vd.value +// +// } +// +// // TODO: Shouldn't be here, this should be implemented on Ray if it's general enough +// get domain(): Ray { return JS.Iterable([this.vtype, this.size]) }; +// +// } +// +// export class EData extends Ray { +// +// fg = this.property('bg', Color()); +// bg = this.property('bg', Color()); +// x = this.property('y', int(0)); +// // y-coordinate at which to draw the vertex. +// y = this.property('y', int(0)); +// highlight = this.property('highlight', bool(False)) +// hyper = this.property('value', bool(True)) +// value = this.property('value') +// +// __repr__ = (): Ray => { throw new NotImplementedError(); +// // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' +// } +// +// // TODO: More stuff to relate it to the screen that shouldnt be here. +// /** +// * Return how many width 'units' this box needs to display nicely. +// * +// * This uses a simple rule: +// * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. +// * - Otherwise draw as a larger (size 2) box. +// */ +// box_size = (): Ray => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); +// +// domain = (): Ray => this.source.cast().domain; +// codomain = (): Ray => this.target.cast().domain; +// +// toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL +// } +// +// /** +// * A hypergraph with boundaries. +// * +// * This is the main data structure used by Chyp. It represents a directed +// * hypergraph (which we call simply a "graph") as two dictionaries for +// * vertices and (hyper)edges, respectively. Each vertex is associated with a +// * `VData` object and edge edge with an `EData` object, which stores +// * information about adjacency, position, label, etc. +// * +// * The particular flavor of hypergraphs we use associate to each hyperedge a +// * list of source vertices and a list of target vertices. The hypergraph +// * itself also has a list of input vertices and a list of output vertices, +// * which are used for sequential composition and rewriting. +// */ +// export class Graph extends Ray { +// +// get vindex(): Ray { return this.vdata.index.max(0); } +// get eindex(): Ray { return this.edata.index.max(0); } +// +// // Mapping from integer identifiers of each vertex to its data. +// vdata = this.property('vertices'); +// // Mapping from integer identifiers of each hyperedge to its data. +// edata = this.property('edges'); +// +// // TODO .keys +// vertices = this.property('vertices'); +// edges = this.property('edges'); +// +// /** +// * Return the domain of the graph. +// * +// * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. +// */ +// // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. +// get domain(): Ray { return this.inputs.cast().domain; }; +// +// /** +// * Return the domain of the graph. +// * +// * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. +// */ +// get codomain(): Ray { return this.outputs.cast().domain; }; +// +// vertex_data = (v = int): VData => this.vertices().at(v).cast(); +// edge_data = (e = int): EData => this.edges().at(e).cast(); +// +// // TODO: Shouldnt be here +// ___next_index = (name = int(-1), index: Ray): Ray => { +// // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) +// const current = name === -1 ? index : Math.max(name, index); +// return current + 1; +// } +// +// /** +// * Add a new vertex to the graph. +// * +// * @param name The value carried by this vertex (currently unused). +// * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. +// * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). +// */ +// add_vertex = (name = int(-1), vertex: VData): VData => { +// this.vindex = this.___next_index(name, this.vindex); +// +// this.vdata[this.vindex - 1] = vertex; +// return vertex; +// } +// +// /** +// * Add a new hyperedge to the graph. +// * +// * @param s +// * @param t +// */ +// add_edge = (name = int(-1), edge: EData): EData => { +// this.eindex = this.___next_index(name, this.eindex); +// +// this.edata[this.eindex - 1] = edge; +// +// // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) +// // for v in s: +// // self.vdata[v].out_edges.add(e) +// // for v in t: +// // self.vdata[v].in_edges.add(e) +// +// return edge; +// } +// // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. +// +// /** +// * Remove a vertex from the graph. +// * +// * This removes a single vertex. +// * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. +// * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. +// * +// * @param v +// * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. +// */ +// remove_vertex = (v = int, strict: boolean = false): Ray => { +// // TODO: destroy any reference of it (could just do this lazy) +// // TODO: as delegation +// +// if (strict) { +// if (this.vertex_data(v).in_edges.count.as_int() > 0 || this.vertex_data(v).out_edges > 0) { +// throw new ValueError('Attempting to remove vertex with adjacent' +// + 'edges while strict == True.'); +// } +// +// if (this.inputs.includes(v) || this.outputs.includes(v)) { +// throw new ValueError('Attempting to remove boundary vertex while' +// + 'strict == True.'); +// +// }// TODO CAN BE SIMPLIFIED +// } +// +// // in/out edges from all vertices +// delete this.vdata[v]; +// } +// +// /** +// * Remove an edge from the graph. +// * +// * @param e Integer identifier of the edge to remove. +// */ +// remove_edge = (e = int): Ray => { +// // TODO: destroy any reference of it (could just do this lazy) +// // in/out edges from all vertices +// delete this.edata[e]; +// } +// +// // TODO: Can these be overlaoded in properties using -=, += in TS? +// +// +// +// +// // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. +// +// +// +// // set function: +// // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs +// // inputs =, outputs = +// // for the add functions: // TODO: Perhaps splat +// // also for add // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) +// +// +// /** +// * Return vertices that lie on a directed path from any of `vs`. +// * // TODO: Just traverse the rays, deduplicate using the index +// */ +// successors = (ray: Ray): Ray => ray.next; +// +// /** +// * Split a vertex into copies for each input, output, and tentacle. +// * +// * This is used for computing pushout complements of rules that aren't left-linear. +// * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). +// * +// * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. +// * +// * @param v Integer identifier of vertex to be exploded. +// */ +// explode_vertex = (v = int): Ray => { +// const vertex = this.vertex_data(v); +// +// // TODO; This just seems like another copy which minor changes +// +// const next_inputs = empty(); +// const next_outputs = empty(); +// +// const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process +// vertex: VData, +// boundary: (vertex: VData) => Ray, +// next_boundary: Ray +// ) => { +// // TODO: It's just a duplicated process for vertex/edge since their definition is separataed +// +// // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. +// // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs]) +// // TODO: Basically a copy, and replace this one vertex +// +// // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. +// boundary(vertex).all(e => { +// const edge: EData = e.cast(); +// +// edge.t = edge.t +// .map(target => { +// if (target === v) +// return target; +// +// const fresh_vertex = vertex.fresh(); +// next_boundary.add(this.add_vertex(fresh_vertex)) +// boundary(fresh_vertex).add(edge); +// }) +// }); +// +// } +// +// // TODO: It's always just duplicated for both ends, +// __temp(vertex, (vertex) => vertex.in_edges, next_inputs); +// __temp(vertex, (vertex) => vertex.out_edges, next_outputs); +// +// // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. +// vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal +// vertex.out_edges.clear(); +// +// // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). +// this.remove_vertex(vertex, true); +// +// return [next_inputs, next_outputs]; +// } +// +// +// /** +// * Insert a new identity hyperedge after the given vertex. +// * +// * A new vertex is also created, which replaces the original vertex as the source of any edges in graph as well as any occurrences of the original vertex in the graph outputs. +// * +// * @param reverse +// * - If `False`, the original vertex becomes the source of the ew identity hyperedge while the new vertex becomes the target. +// * - If `True`, the source and target of the new identity are flipped. This can be used to break directed cycles, by neffectively introducing a cap and cup. +// */ +// insert_id_after = (v = int, reverse = bool(False)): Ray => { +// const vertex = this.vertex_data(v); +// +// // Create a new vertex with the same vtype and size +// // //TODO ; Which is this .fresh +// const new_vertex = vertex.fresh(); +// new_vertex.x += 3; +// // The new vertex is highlighted whenever the orignal vertex is. +// new_vertex.highlight = vertex.highlight; // TODO: This not done by .fresh? +// +// /** +// * //TODO: BEcause it's inserted after, set the output (generalize to just moving the reference to the terminal. +// * # Replace any occurences of the original vertex in the graph outputs +// * # with the new vertex. +// * self.set_outputs([x if x != v else w for x in self.outputs()]) +// */ +// +// // Where the original vertex is the source of a hyperedge, replace it with the new vertex and register this change with the data instance of each vertex +// // TODO syncs the out_edges fields, wd.out_edges.add(e) vd.out_edges.clear() +// // TODO replace out_edges.source to new_vertex again +// +// // Assign the orignal and new vertex as source or target of the new identity edge, based on the `reverse` argument. +// // TODO: Sets reverse just flipping around the initial/terminal.. +// // TODO: s, t = ([v], [w]) if not reverse else ([w], [v]) +// +// // Create the new identity edge. +// const edge = this.add_edge() // s, t, 'id', vd.x + 1.5, vd.y) +// edge.hightlight = vertex.highlight; // The new edge is highlighted whenever the original vertex is. +// +// return edge; +// } +// +// /** +// * Take the monoidal product of this graph in-place with another. +// * +// * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. +// * +// * @param other +// * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. +// */ +// tensor = (other: Graph, layout: boolean = true): Ray => { +// +// const a = this; +// const b = other; +// +// const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] +// +// tensor.initial.any.y -= +// tensor.initial.any.y.max(); // max_self +// +// tensor.terminal.any.y -= +// (layout ? tensor.terminal.any.y.min() : 0) + 1; // min_other TODO: Why + 1 ? +// +// /** +// * # self.set_inputs(self.inputs + [vmap[v] for v in other.inputs]) +// * # self.set_outputs(self.outputs + [vmap[v] for v in other.outputs]) +// * +// * # Add the inputs and outputs of the other graph to this one. +// * self.add_inputs([vmap[v] for v in other.inputs]) +// * self.add_outputs([vmap[v] for v in other.outputs]) +// */ +// // TODO: Add equivalence/reference on the inputs/output extremes. +// } +// +// /** +// * Sequentially compose this graph in-place with another. +// * +// * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. +// */ +// compose = (other: Graph): Ray => { +// // TODO Just matching outputs and inputs.. +// +// // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" +// +// // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs +// +// /** +// * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. +// */ +// +// // Compute the max x-coordinate of the edges and vertices in this graph. +// +// // TODO: Again, recursively going through everything defined on the initial side (outputs) +// // Shift all vertices and edges of this graph below the x-axis. +// compose.initial.any.x -= +// compose.initial.any.x.max(); // max_self +// +// // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] +// compose.terminal.any.x -= +// compose.terminal.any.x.min(); // min_other +// +// // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. +// /** +// * plug1 = self.outputs +// * plug2 = [vmap[v] for v in other.inputs] +// * +// * if len(plug1) != len(plug2): +// * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' +// * + f'outputs into one with {len(plug2)} inputs') +// * +// * self.set_outputs([vmap[v] for v in other.outputs]) +// */ +// +// // [outputs to inputs] +// // Go through pairs of vertices from each plug +// compose.zip().all(([input, output]) => { +// /** +// * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. +// */ +// +// // TODO: does this ever happen??? +// // while p1 in quotient: +// // p1 = quotient[p1] +// // while p2 in quotient: +// // p2 = quotient[p2] +// +// +// // TODO, Again the same equivalence check for loops etc.. +// { +// // If the resulting p1 and p2 are not the same vertex, merge them. +// if (input === output) +// return; +// +// // TODO; DO this on the vertices; +// // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) +// +// // If both vertices have flexible types that are not equal, raise an error due to ambiguity. +// // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. +// +// +// // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. +// +// ['vtype', 'size'].forEach(structure => { +// const infer = `infer_${structure}`; +// +// if (input[infer] && output[infer] && input[structure] !== output[structure]) { +// throw GraphError(`Ambiguous vertex ${structure} during composition.`) +// +// } else if (input[infer]) { +// // Otherwise, if one vertex has a flexible type, ensure the vertex types match. +// // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it +// // TODO: Again both sides same thing.. +// input[structure] = output[structure]; // TODO: Generalized structure +// input[infer] = false; +// } else if (output.infer_type) { +// output[structure] = input[structure]; +// output[infer] = false; +// } +// }); +// +// input.merge(output); +// // # Register than p2 has been merged into p1. +// // quotient[p2] = p1 +// } +// }); +// } +// +// /** +// * Return the tensor product of this graph with another. +// * +// * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them +// */ +// __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); +// +// /** +// * Return the composition of the current graph with `other`. +// * +// * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. +// * @param other +// */ +// __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); +// +// /** +// * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer +// */ +// ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { +// const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. +// something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? +// return a_copy; // Could generalize to either end +// } +// +// /** +// * Set the `highlight` flag for a set of vertices and edges. +// * +// * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. +// * +// * @param vertices A set of vertices to highlight. +// * @param edges A set of edges to highlight. +// */ +// highlight = (vertices = set(int), edges = set(int)): Ray => { +// // TODO Again, these could be merged +// this.vdata +// .filter(vertex => vertices.includes(vertex)) +// .all(vertex => vertex.cast().highlight = bool(true)); +// this.edata +// .filter(edge => edges.includes(edge)) +// .all(edge => edge.cast().highlight = bool(true)); +// +// } +// +// /** +// * Clear the `highlight` flag for all vertices/edges. +// * +// * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. +// */ +// unhighlight = (): Ray => { +// // TODO: These could be merged +// this.vdata.highlight = false; +// this.edata.highlight = false; +// } +// +// /** +// * Return matches of domain into codomain. +// */ +// match = (other: Graph, convex: boolean = true): Matches => new Matches(this, other, convex); +// +// /** +// * Return an isomorphism between graphs g and h if found, otherwise `None`. +// * +// * If found, the isomorphism is returned as a :py:class:`Matches` instance, whose vertex and edge maps are bijections. +// */ +// find_iso = (other: Graph): Match => { // TODO | NONE +// +// // TODO: Again, more equivalence checks +// // First, check the domains and codomains are equal between the two graphs. +// if (this.domain !== other.domain || this.codomain !== other.codomain) +// return None; //TODO +// +// // Try to find an initial match mapping one of the boundary vertices of the domain graph to the corresponding boundary vertex (the vertex in the same input/output location) of the codomain graph. If no initial match is found, return `None`. +// const initial_match = new Match(this, other); +// +// const ___temp = (func: (ray: Graph) => Ray) => { +// ([func(this), func(other)] as Ray).zip(([initial, terminal]) => { +// if (!initial_match.try_add_vertex(initial, terminal)) +// return None; //TODO, DOESNT ACTUALLY RETURN THE FUNCTION HERE. Wait till matcher is abstracted to fix this +// }); +// } +// +// ___temp(ray => ray.inputs); +// ___temp(ray => ray.outputs); // TODO: See again, the same pattern over and over again, same on both sides. +// +// // If an initial match is found, try to find a total and surjective match of the domain graph into the codomain graph. +// +// return new Matches(this, other, initial_match, false) +// .filter(match => match.is_surjective()); // TODO; With this filter it should allow you to keep looking +// +// // TODO::: Automatic?? +// // If a total surjective match is not found, return `None`. +// return None; +// } +// } +// +// export class Chyp extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// +// /** +// * Load a .chyp graph file from the given path. +// */ +// load_graph = (path = str) => { +// // TODO: From localStorage for now? +// // with open(path) as f: +// // g = graph_from_json(f.read()) +// } +// +// /** +// * Return a graph corresponding to the identity map. +// * +// * This graph has a single vertex which is both an input and an output. +// */ +// identity = (vertex: VData): Graph => { +// const graph = new Graph(); +// +// vertex.x = 0; // TODO automatic>? +// vertex.y = 0; +// graph.add_vertex(int(-1), vertex); +// // TODO synce input/output automatically? +// // g.set_inputs([v]) +// // g.set_outputs([v]) +// +// return graph; +// } +// +// +// ___map_domain = (domain: Ray, _default: VData): Ray => { +// return domain.map(([vtype, size], i) => { +// const vertex: VData = _default.copy().cast(); +// // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere +// vertex.x = -1.5; +// vertex.y = i - (i-1) / 2; +// +// return vertex; +// }) +// } +// +// /** +// * Return a graph with one hyperedge and given domain and codomain. +// * +// * @param _default +// * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. +// * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. +// */ +// gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { +// const graph = new Graph(); +// +// const inputs = this.___map_domain(domain, _default) +// .map(vertex => graph.add_vertex(vertex)); +// const outputs = this.___map_domain(codomain, _default) +// .map(vertex => graph.add_vertex(vertex)); +// +// // TODO This is probably automatic at some point, remove +// const edge = new EData(); +// edge.s = inputs; +// edge.t = outputs; +// graph.add_edge(int(-1), edge); +// // g.set_inputs(inputs) +// // g.set_outputs(outputs) +// +// return graph; +// } +// +// /** +// * Return a graph corresponding to the given permutation. +// * +// * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. +// * +// * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. +// * +// * @param p A permutation given as an n-element list of integers from 0 to n-1. +// * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. +// */ +// perm = (p = list(int), domain: Ray, _default: VData) => { +// +// const graph = new Graph(); +// const num_wires = p.count.as_int(); +// +// if (num_wires !== domain.count.as_int()) +// throw new GraphError(`Domain ${domain} does not match length of permutation.`) +// +// // TODO use ___map_domain +// const inputs = domain.map(([vtype, size], i) => { +// const vertex: VData = _default.copy().cast(); +// // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere +// vertex.x = 0; +// vertex.y = i - (num_wires - 1) / 2; +// +// return vertex; +// }) +// .map(vertex => graph.add_vertex(vertex)); +// // const outputs = num_wires.range(i => [inputs[p[i]]) +// +// // TODO Should be automatic +// // g.set_inputs(inputs) +// // g.set_outputs(outputs) +// return graph; +// } +// +// graph_from_json = (json_string = str): Graph => { +// const json = JSON.parse(json_string().as_string()); // TODO +// +// const graph = new Graph(); +// +// // TODO: Don't do this so naively +// // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), +// // y=float(vd["y"] if "y" in vd else 0.0), +// // value=vd["value"] if "value" in vd else "", +// // name=int(v)) +// // for e, ed in j["edges"].items(): +// // g.add_edge(s=[int(v) for v in ed["s"]], +// // t=[int(v) for v in ed["t"]], +// // value=ed["value"] if "value" in ed else "", +// // x=float(ed["x"]) if "x" in ed else 0.0, +// // y=float(ed["y"]) if "y" in ed else 0.0, +// // hyper=bool(ed["hyper"]) if "hyper" in ed else True, +// // name=int(e)) +// // +// // g.set_inputs([int(v) for v in j["inputs"]]) +// // g.set_outputs([int(v) for v in j["outputs"]]) +// // json.vertices.forEach(((vertex, i) => graph.add_vertex( +// // i, +// // new VData() +// // )); +// +// return graph; +// } +// +// /** +// * # def wide_id() -> Graph: +// * # return gen("id", 1, 1) +// * +// * # def id_perm(p: List[int]) -> Graph: +// * # g = Graph() +// * # size = len(p) +// * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] +// * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] +// * +// * # for i in range(size): +// * # y = i - (size-1)/2 +// * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) +// * +// * # g.set_inputs(inputs) +// * # g.set_outputs(outputs) +// * +// * # return g +// */ +// +// /** +// * Return a graph corresponding to a vertex size redistribution. +// * +// * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. +// * +// * More generally, a conversion can be done between different lists of sizes, for some vertex type. +// * +// * @param domain A list of pairs (vertex type, register size) corresponding to each input vertex. +// * @param codomain A list of pairs (vertex type, register size) corresponding to each output vertex. +// */ +// redistributer = (domain = list, codomain = list) => { +// /** +// * vtypes = set(vtype for vtype, _ in domain) +// * vtypes.update(vtype for vtype, _ in codomain) +// * if len(vtypes) > 1: +// * raise GraphError('Size conversion cannot mix vertex types.') +// * +// * # Raise error if size conservation is violated +// * domain_size = sum(size for _, size in domain) +// * codomain_size = sum(size for _, size in codomain) +// * if domain_size != codomain_size: +// * raise GraphError(f'Sum of domain sizes ({domain_size}) does not equal' +// * + f'sum of codomain sizes ({codomain_size}).') +// * +// * return gen('_redistributer', domain, codomain) +// */ +// +// } +// +// /** +// * Some more delegations here +// */ +// match_graph = (domain: Graph, codomain: Graph, convex: boolean = true): Matches => domain.match(codomain, convex); +// match_rule = (rule: Rule, codomain: Graph, convex: boolean = true): Matches => rule.match(codomain, convex); +// find_iso = (domain: Graph, codomain: Graph): Match => domain.find_iso(codomain); +// } +// +// export class CodeView extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// popup_visible = (): Ray => { throw new NotImplementedError(); } +// set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } +// ident_at_cursor = (): Ray => { throw new NotImplementedError(); } +// insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } +// keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } +// set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } +// add_line_below = (text = str): Ray => { throw new NotImplementedError(); } +// } +// +// export class CodeCompletionModel extends Ray { +// __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } +// set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } +// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } +// rowCount = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class ChypDocument extends Ray { +// __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } +// confirm_close = (): Ray => { throw new NotImplementedError(); } +// add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } +// open = (file_name = str): Ray => { throw new NotImplementedError(); } +// save = (): Ray => { throw new NotImplementedError(); } +// save_as = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class Editor extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// title = (): Ray => { throw new NotImplementedError(); } +// reset_state = (): Ray => { throw new NotImplementedError(); } +// invalidate_text = (): Ray => { throw new NotImplementedError(); } +// next_part = (): Ray => { throw new NotImplementedError(); } +// jump_to_error = (): Ray => { throw new NotImplementedError(); } +// show_errors = (): Ray => { throw new NotImplementedError(); } +// show_at_cursor = (): Ray => { throw new NotImplementedError(); } +// next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } +// repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } +// update_state = (): Ray => { throw new NotImplementedError(); } +// import_at_cursor = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class CheckThread extends Ray { +// __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } +// run = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class ErrorListModel extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } +// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } +// headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } +// index = (row = int, column = int): Ray => { throw new NotImplementedError(); } +// columnCount = (): Ray => { throw new NotImplementedError(); } +// rowCount = (): Ray => { throw new NotImplementedError(); } +// parent = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class EItem extends Ray { +// __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } +// paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } +// } +// +// export class VItem extends Ray { +// __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } +// refresh = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class TItem extends Ray { +// __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } +// refresh = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class GraphScene extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } +// add_items = (): Ray => { throw new NotImplementedError(); } +// mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } +// mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } +// mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } +// } +// +// export class GraphView extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } +// } +// +// export class ChypHighlighter extends Ray { +// __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } +// set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } +// highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } +// } +// +// export class MainWindow extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// remove_empty_editor = (): Ray => { throw new NotImplementedError(); } +// update_file_name = (): Ray => { throw new NotImplementedError(); } +// tab_changed = (i = int): Ray => { throw new NotImplementedError(); } +// update_themes = (): Ray => { throw new NotImplementedError(); } +// recent_files = (): Ray => { throw new NotImplementedError(); } +// update_recent_files = (): Ray => { throw new NotImplementedError(); } +// add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } +// close_tab = (): Ray => { throw new NotImplementedError(); } +// new = (): Ray => { throw new NotImplementedError(); } +// open = (): Ray => { throw new NotImplementedError(); } +// save = (): Ray => { throw new NotImplementedError(); } +// save_as = (): Ray => { throw new NotImplementedError(); } +// undo = (): Ray => { throw new NotImplementedError(); } +// redo = (): Ray => { throw new NotImplementedError(); } +// show_errors = (): Ray => { throw new NotImplementedError(); } +// add_rewrite_step = (): Ray => { throw new NotImplementedError(); } +// repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } +// next_rewrite = (): Ray => { throw new NotImplementedError(); } +// next_part = (): Ray => { throw new NotImplementedError(); } +// previous_part = (): Ray => { throw new NotImplementedError(); } +// next_tab = (): Ray => { throw new NotImplementedError(); } +// previous_tab = (): Ray => { throw new NotImplementedError(); } +// goto_import = (): Ray => { throw new NotImplementedError(); } +// closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } +// build_menu = (): Ray => { throw new NotImplementedError(); } +// } +// +// // TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? +// export class Match extends Ray { +// +// get vertex_map(): Ray { throw new NotImplementedError(); } +// get vertex_image(): Ray { throw new NotImplementedError(); } +// get edge_map(): Ray { throw new NotImplementedError(); } +// get edge_image(): Ray { throw new NotImplementedError(); } +// +// __str__ = (): Ray => { +// // (f'\tVertex map: {str(self.vertex_map)}' +// // + f'\n\tEdge map: {str(self.edge_map)}') +// // TODO +// throw new NotImplementedError(); } +// +// // Implemented on Ray +// // TODO; doesnt copy the graphs at domain/codomain +// // copy = (): Ray => { throw new NotImplementedError(); } +// +// /** +// * Try to map `domain_vertex` to `codomain_vertex`. +// * +// * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. +// * +// * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. +// */ +// try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { +// +// // If the vertex is already mapped, only check the new mapping is consistent with the current match. +// if (this.vertex_map.includes(domain_vertex)) { +// log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) +// return this.vertex_map[domain_vertex] === codomain_vertex; +// } +// +// // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. +// // TODO: This should all be redundant, probably removed ... +// +// // Ensure the mapping preserves vertex type. +// if (domain_vertex.vtype !== codomain_vertex.vtype) { +// log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); +// +// return bool(False); +// } +// +// // Ensure the mapping preserves vertex size. +// if (domain_vertex.size !== codomain_vertex.size) { +// log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) +// return bool(False); +// } +// +// // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. +// if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { +// log('Vertex failed: codomain vertex is boundary but domain vertex is not.') +// return bool(False); +// } +// +// // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. +// if (this.vertex_image.includes(codomain_vertex)) { +// // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. +// if (!domain_vertex.is_boundary()) { +// log('Vertex failed: non-injective on interior vertex.') +// return bool(False); +// } +// +// // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. +// if (this.vertex_image.any(([mapped_vertex, image_vertex]) => +// image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! +// )) { +// log('Vertex failed: non-injective on interior vertex.') +// return bool(False); +// } +// +// return bool(False); +// } +// +// // If a new and consistent map is found, add it to the vertex map of this match. +// this.vertex_map[domain_vertex] = codomain_vertex +// this.vertex_image.add(codomain_vertex) +// +// // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. +// +// if (!domain_vertex.is_boundary()) { +// if (domain_vertex.in_edges.count.as_int() !== codomain_vertex.in_edges.count.as_int()) { +// log('Vertex failed: in_edges cannot satisfy gluing conditions.') +// return bool(False) +// } +// if (domain_vertex.out_edges.count.as_int() !== codomain_vertex.out_edges.count.as_int()) { +// log('Vertex failed: in_edges cannot satisfy gluing conditions.') +// return bool(False) +// } +// } +// +// // If a new consistent map is added that satisfies the gluing conditions, we are successful. +// log('Vertex success.') +// return bool(True); +// } +// +// /** +// * Try to map `domain_edge` to `codomain_edge`. +// * +// * This must satisfy certain conditions, such as being injective and having consistency with the vertex map. +// * +// * @param domain_edge +// * @param codomain_edge +// * +// * `True` if a consistent match is found mapping `domain_edge` to `codomain_edge`, otherwise `False`. +// */ +// try_add_edge = (initial: EData, terminal: EData): Ray => { +// log(`Trying to add edge ${initial} -> ${terminal} to match:`); +// log(this.toString()); +// +// // TODO: Again an equivalence +// // Check the values of the domain and codomain edges match. +// if (initial.value !== terminal.value) { +// log(`Edge failed: values ${initial.value} != ${terminal.value}`) +// return false; +// } +// +// // The edge map must be injective. +// if (this.edge_image.includes(terminal)) { +// console.log('Edge failed: the map would become non-injective.'); +// return false; +// } +// +// // If the values match and the codomain edge has not already been mapped to, map domain edge to codomain edge. +// this.edge_map[initial] = terminal; +// this.edge_image.add(terminal); +// +// // Domain sources must match codomain sources and domain targets must match codomain targets. +// +// // TODO: Again more equivalences, just to log - debug mode +// { +// // initial = preimg +// // terminal = image +// +// // Domain sources must match codomain sources and domain targets must match codomain targets. +// if (initial.domain !== terminal.domain) { +// log(`Edge domain ${initial.domain} does not match image domain ${terminal.domain}.`); +// } +// +// // TODO, again both sides +// if (initial.codomain !== terminal.codomain) { +// log(`Edge codomain ${initial.codomain} does not match image codomain ${terminal.codomain}.`); +// } +// } +// +// // TODO: This too probably general pattern to extract +// // Check a vertex map consistent with this edge pairing exists. +// // TODO: + here is just concat, so that zip can easily match it +// ([initial.source + initial.target, terminal.source + terminal.target] as Ray).zip(([initial_vertex, terminal_vertex]) => { +// // Each vertex that is already mapped needs to be consistent. +// // TODO: More equivlaency, could be on the vertecies themselves +// if (this.vertex_map.includes(initial_vertex) && this.vertex_image[initial_vertex] !== terminal_vertex) { +// log('Edge failed: inconsistent with previously mapped vertex.'); +// return false; // TODO: NOT RETURNING AGAIN +// } +// +// // Otherwise, a consistent match must be found vertex for unmapped source and target vertices. +// +// if (!this.try_add_vertex(initial_vertex, terminal_vertex)) { +// log('Edge failed: couldn\'t add a source or target vertex.'); +// return false; +// } +// }); +// +// log('Edge success.'); +// return true; +// } +// +// /** +// * Return whether all adjacent edges of a domain vertex are mapped. +// */ +// domain_neighbourhood_mapped = (vertex: VData): Ray => +// ([vertex.in_edges + vertex.out_edges] as Ray).all(edge => this.edge_map.includes(edge)); +// +// /** +// * # def cod_nhd_mapped(self, cod_v: int): +// * # """Returns True if nhd(cod_v) is the range of emap""" +// * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and +// * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) +// */ +// +// /** +// * Try to extend the match by mapping all scalars (i.e. 0 -> 0 edges). +// * +// * Note that any matchings of scalars will yield isomorphic results under rewriting, so we don't return a list of all the possible matchings. +// * +// * Returns: `True` if all scalars in the domain are mapped injectively to scalars in the codomain, otherwise `False`. +// */ +// map_scalars = (): Ray => { +// //TODO WHAT'S A SCALAR HERE? +// // TODO: Again same pattern for (co)domain - flipped, two dimensional +// const ___scalars = (domain: Graph, reverse: boolean) => { +// const is = (ray: Ray) => reverse ? ray.count !== 0 : ray.count === 0; // TODO: Should be easier to just .not this +// +// return domain.edges +// .filter((edge: EData) => this.is(edge.source) && this.is(edge.target)); +// } +// +// const terminal = ___scalars(this.codomain, false); +// const initial = ___scalars(this.domain, true); +// +// // Greedily try to map scalar edges in the domain to scalar edges in the codomain with the same value. +// initial.all((initial_edge: EData) => { +// // TODO: Put initial/terminal edge on a ray and then apply funcitons +// +// log(`Trying to map scalar edge ${initial_edge}`) +// +// let found_match = false; +// +// // TODO .enumerate?? +// terminal.all(([i, terminal_edge]) => { +// if (initial_edge.value !== terminal_edge.value) // ANother equiv +// return; // TODO continue; +// +// // Map the domain scalar to the first codomain scalar available with the same value. +// this.edge_map[initial_edge] = terminal_edge; +// this.edge_image.add(terminal_edge); // TODO: Again map/image is just initial/terminal.. same as domain/codomain,, +// +// found_match = true; +// +// // Since the edge map must be injective, if a scalar in the codomain is mapped to, remove it from the list of candidates for future domain scalars to be mapped to. +// terminal.pop(i); // TODO: ??? +// +// log(`Successfully mapped scalar ${initial_edge} -> ${terminal_edge}`) +// +// // TODO: BREAK ; any?? +// }); +// +// if (!found_match) { +// log(`Match failed: could not map scalar edge ${initial_edge}.`) +// return false; // TODO DOESNT RETURN +// } +// }); +// +// return true; +// } +// +// +// // TODO: IF MORE JUST ADDS MORE MATCHES IN THIS DIRECTION, THAT SHOULD BE AUTOMATIC ON .match ... ? +// /** +// * Return any matches extending `self` by a single vertex or edge. +// */ +// more = (): Ray => { +// // First, try to add an edge adjacent to any domain vertices that have already been matched. +// this.vertex_map +// // If all the edges adjacent to the current vertex have already been matched, continue. TODO: Could just be on the .vertex +// .filter(initial_vertex => this.domain_neighbourhood_mapped(initial_vertex)) +// .all((initial_vertex: VData) => { +// // TODO: AS ZIp or something +// const terminal_vertex = this.vertex_map[initial_vertex]; +// +// const ___test = (boundary: (ray: Graph) => Ray): Ray => { +// // Try to extend the match by mapping an adjacent source edge. +// boundary(this.domain) // TODO: AGAIN SAME THING +// // If the edge has already been matched, continue. +// .filter(edge => !this.edge_map.includes(edge)) +// .all((initial_edge: EData) => { +// +// // Otherwise, try to map this edge into the codomain graph. +// return boundary(this.codomain).map(terminal_edge => { +// const potential_new_match = this.copy(); +// +// // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. +// if (potential_new_match.try_add_edge(initial_edge, terminal_edge)) +// return potential_new_match; +// +// return NONE;//todo +// }); // TODO REMOVE NON-ADDED_ONES, doesnt actually reutn either +// }) +// +// } +// +// ___test(ray => ray.in_edges); +// ___test(ray => ray.out_edges); +// +// }); +// +// // If all domain edges adjacent to matched domain vertices have already been matched, try to match an unmatched domain vertex. +// this.domain.vertices +// // If the vertex has already been matched into the codomain graph, continue. (Note we have looked at the edge-neighbourhood of these vertices above) +// .filter(initial_vertex => this.vertex_map.includes(initial_vertex)) // TODO: THIS THING IS JUST A COPY, AGAIN FROM THE VERTEX/EDGE DIFFERENTIATION FROM ABOVE +// .all(initial_vertex => { +// +// // Try to map the current domain vertex to any of the codomain vertices, extending the current match with this map when successful. +// return this.codomain.vertices.map((terminal_vertex: VData) => { +// const potential_new_match = this.copy(); +// +// // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. +// if (potential_new_match.try_add_vertex(initial_edge, terminal_edge)) +// return potential_new_match; +// +// return NONE;//todo +// }); // TODO: AGAIN DOESNT RETURN +// }) +// +// return []; +// } +// +// // TODO: Total=surjective on another level of description ??? +// ___defuq = (string: 'image' | 'map', domain) => +// this[`vertex_${string}`].count === domain.vertices.count +// && this[`edge_${string}`].count === domain.edges.count; // TODO: Again vertex/edge pattern, just collapse to one check +// +// /** +// * Return whether all domain vertices and edges have been mapped. +// */ +// is_total = (): Ray => this.___defuq('map', this.domain); +// /** +// * Return whether the vertex and edge maps are surjective. +// */ +// is_surjective = (): Ray => this.___defuq('image', this.codomain); +// +// /** +// * Return whether the vertex and edge maps are injective. +// */ +// is_injective = (): Ray => { +// // Since the edge map is always injective, we only need to check the vertex map is injective. TODO (GENERALIZE) +// return this.vertex_map.count === this.vertex_image.count; +// } +// +// /** +// * Return whether this match is convex. +// * +// * A match is convex if: +// * - It is injective. +// * - Its image in the codomain hypergraph is a convex sub-hypergraph. This means that for any two nodes in the sub-hypergraph and any path between these two nodes, every hyperedge along the path is also in the sub-hypergraph. +// * +// * TODO: Just no overlap?? +// */ +// is_convex = (): Ray => { +// if (!this.is_injective()) { //TODO: WHY? +// return false; +// } +// +// +// // Check that the image sub-hypergraph is convex. Get all successors of vertices in the image of the output of the domain graph. +// const output_image_successors = this.codomain.successors( +// this.domain.outputs +// .filter(vertex => this.vertex_map[vertex]) // TODO INCLUDES +// ); // TODO, Why search in codomain fromi these, ?? this must be easier +// +// // Check there is no path from any vertices in the image of the domain outputs to a vertex in the image of the domain inputs. +// this.domain.inputs +// .filter(vertex => this.vertex_map.includes(vertex) && output_image_successors.includes(this.vertex_map[vertex])) +// .any(() => { return false }) // TODO DOESNT ACTUALLY RETURNM +// +// return true; +// } +// +// /** +// * TODO Not implemented;; +// * # def cod_nhd_mapped(self, cod_v: int): +// * # """Returns True if nhd(cod_v) is the range of emap""" +// * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and +// * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) +// */ +// } +// +// /** +// * An iterator over matches of one graph into another. +// * +// * This class can be used to iterate over total matches of a graph into another, optionally requiring these matches to be convex. +// * +// * TODO: SUPPORT THIS/?::: +// * A class instance works by keeping a stack of partial or total matches. +// * When it is iterated over, it pops a match from its match stack if it is +// * non-empty, otherwise the iteration is stopped. If a match has been popped, +// * the instance returns the match if it is total (and convex if required). +// * Otherwise, the instance tries to extend the match and add any extended +// * matches to the stack, then continues this process of popping off the match +// * stack and extending if possible until a valid match is found and returned. +// */ +// export class Matches extends Ray { +// __init__ = (domain = Graph, codomain = Graph): Ray => { +// /** +// * TODO +// * if initial_match is None: +// * initial_match = Match(domain=domain, codomain=codomain) +// * self.convex = convex +// * +// * # Try to map scalars on the initial match. +// * if initial_match.map_scalars(): +// * self.match_stack = [initial_match] +// * # If the scalars could not be mapped, set the match +// * # stack to be empty. This means that not suitable matches +// * # will be found by this class instance. +// * else: +// * self.match_stack = [] +// */ +// throw new NotImplementedError(); } +// __iter__ = (): Ray => { throw new NotImplementedError(); } +// +// /** +// * Return the next suitable match found. +// * +// * A 'suitable' match is one that is total and, if `self.convex == True`, convex. +// */ +// __next__ = (): Ray => { +// // TODO Like expected this, class can probably be dropped this just becomes +// +// return this.match_stack.dont_check_for_convex_or.is_convex; // TODO: Just generalize these on functions +// +// /** +// * while len(self.match_stack) > 0: +// * # Pop the match at the top of the match stack +// * m = self.match_stack.pop() +// * # If the match is total (and convex if required), return it. +// * if m.is_total(): +// * match_log("got successful match:\n" + str(m)) +// * if self.convex: +// * if m.is_convex(): +// * match_log("match is convex, returning") +// * return m +// * else: +// * match_log("match is not convex, dropping") +// * else: +// * return m +// * # If the match at the top of the match stack was not total +// * # (and convex if required), try to extend the match at the +// * # top of the stack and add the results to the match stack. +// * else: +// * self.match_stack += m.more() +// * # If a suitable match was not found, stop the iteration. +// * raise StopIteration +// */ +// } +// } +// +// export class Rule extends Ray { +// +// get equiv(): Ray { throw new NotImplementedError(); } +// +// +// /** +// * Returns True if boundary on lhs embeds injectively +// */ +// is_left_linear = (): Ray => { +// // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading +// return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() +// .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. +// } +// +// /** +// * Do double-pushout rewriting +// * +// * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. +// * @param match +// */ +// dpo = (match: Match): Ray => { +// // if (!this.is_left_linear()) +// // throw new NotImplementedError("Only left linear rules are supported for now") +// +// const rewritten_graph: Graph = match.codomain.copy(); +// +// // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? +// +// // Computes the push complement ?? (just the thing we're replacing right?) +// // TODO: Removes the match from the copy? +// this.lhs.edges.all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); +// +// const inputs = []; +// const outputs = []; +// +// this.lhs.vertices.all(rule_vertex => { +// const match_vertex = match.vertex_map[rule_vertex]; +// +// if (!this.lhs.is_boundary(rule_vertex)) { +// rewritten_graph.remove_vertex(match_vertex); +// return; +// } +// +// const rule_input = rule_vertex.in_indices; +// const rule_output = rule_vertex.out_indices; +// +// if (rule_input.count.as_int() === 1 && rule_output === 1) { +// const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); +// +// if (match_input.count.as_int() !== 1 && match_output.count.as_int() !== 1) +// throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); +// +// inputs[rule_vertex] = match_input[0]; +// outputs[rule_vertex] = match_output[0]; +// } else if (rule_input.count.as_int() > 1 || rule_output.count.as_int() > 1) { +// throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); +// } +// }) +// +// // Embed Rule.rhs into rewritten_graph +// const replacement = new Match(this.rhs, rewritten_graph); +// +// // TODO: This is probably another of these geeneral patterns, same thing on either ends composed as a single ray., +// const input = new Ray(); // [this.lhs.inputs, this.rhs.inputs] +// +// // first map the inputs, using the matching of the lhs +// input.zip().all(([initial, terminal]) => { +// match.vertex_map[terminal] = inputs.includes(initial) ? inputs[initial] : match.vertex_map[initial]; +// }); +// +// const output = new Ray(); // [this.lhs.outputs, this.rhs.outputs] +// +// // next map the outputs. if the same vertex is an input and an output in r.rhs, then merge them in h. +// output.zip().all(([initial, terminal]) => { +// // TODO: Again, both ends are very similar, there should probably be a direct flip in these, small difference at the end +// const temp = outputs.includes(initial) ? outputs[initial] : match.vertex_map[initial]; +// +// if (match.vertex_map.includes(terminal)) { +// rewritten_graph.merge_vertices(match.vertex_map[terminal], temp) +// } else { +// match.vertex_map[terminal] = temp; +// } +// }); +// +// // then map the interior to new, fresh vertices +// this.rhs.vertices +// .filter(vertex => !vertex.is_boundary()) +// .all((vertex: VData) => { +// // TODO Again the fresh thing repeated here - just because it's moving between graphs +// const new_vertex = rewritten_graph.add_vertex(vertex.fresh()); +// +// match.vertex_map[vertex] = new_vertex; +// match.vertex_image.add(new_vertex); +// }); +// +// // now add the edges from rhs to h and connect them using vmap1 +// // TODO: Again this should be the same thing as the vertices +// this.rhs.edges. +// all((edge: EData) => { +// const new_edge = rewritten_graph.add_edge(); +// /** +// * e1 = h.add_edge([m1.vertex_map[v] for v in ed.s], +// * [m1.vertex_map[v] for v in ed.t], +// * ed.value, ed.x, ed.y, ed.fg, ed.bg, ed.hyper) +// */ +// +// match.edge_map[edge] = new_edge; +// match.edge_image.add(new_edge); +// }) +// +// return replacement; +// } +// +// // TODO: Can probably just match Rule=Graph, and use only one of these methods?? +// /** +// * Return matches of the left side of `rule` into `graph`. +// */ +// match = (other: Graph, convex: boolean = true): Matches => new Matches(this.lhs, other, convex); +// +// /** +// * Apply the given rewrite r to at match m and return the first result +// * +// * This is a convenience wrapper for `dpo` for when the extra rewrite data isn't needed. +// */ +// rewrite = (match: Match): Ray => this.dpo(match).first.terminal; // .first.codomain +// // TODO; Though .first is used here, something like .any is more appropriate in the sense of: Don't care which one first, just something. +// } +// +// export class RewriteState extends Ray { +// __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } +// check = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class State extends Ray { +// __init__ = (): Ray => { throw new NotImplementedError(); } +// part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } +// part_at = (pos = int): Ray => { throw new NotImplementedError(); } +// var = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// num = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } +// type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } +// id = (items = list(Any)): Ray => { throw new NotImplementedError(); } +// id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } +// eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } +// le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } +// perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } +// size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } +// par = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// color = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// } +// +// export class Tactic extends Ray { +// __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } +// repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } +// error = (message = str): Ray => { throw new NotImplementedError(); } +// has_goal = (): Ray => { throw new NotImplementedError(); } +// global_rules = (): Ray => { throw new NotImplementedError(); } +// lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } +// add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } +// __lhs = (target = str): Ray => { throw new NotImplementedError(); } +// __rhs = (target = str): Ray => { throw new NotImplementedError(); } +// __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } +// __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } +// rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } +// validate_goal = (): Ray => { throw new NotImplementedError(); } +// lhs = (): Ray => { throw new NotImplementedError(); } +// rhs = (): Ray => { throw new NotImplementedError(); } +// lhs_size = (): Ray => { throw new NotImplementedError(); } +// rhs_size = (): Ray => { throw new NotImplementedError(); } +// highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } +// highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } +// __reset = (): Ray => { throw new NotImplementedError(); } +// next_rhs = (current = str): Ray => { throw new NotImplementedError(); } +// run_check = (): Ray => { throw new NotImplementedError(); } +// name = (): Ray => { throw new NotImplementedError(); } +// check = (): Ray => { throw new NotImplementedError(); } +// make_rhs = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class RuleTac extends Ray { +// name = (): Ray => { throw new NotImplementedError(); } +// make_rhs = (): Ray => { throw new NotImplementedError(); } +// check = (): Ray => { throw new NotImplementedError(); } +// } +// +// export class SimpTac extends Ray { +// name = (): Ray => { throw new NotImplementedError(); } +// __prepare_rules = (): Ray => { throw new NotImplementedError(); } +// make_rhs = (): Ray => { throw new NotImplementedError(); } +// check = (): Ray => { throw new NotImplementedError(); } +// } +// diff --git a/src/App.tsx b/src/App.tsx index d88a9ef..49bd462 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -14,6 +14,7 @@ import Modules from "./@orbitmines/js/react/Modules"; import Icons from "./lib/layout/experimental-designs/Icons"; import {ThumbnailPage} from "./lib/paper/Paper"; import {ChypExplorer} from "./@orbitmines/external/chyp/ChypCanvas"; +import {DebugExplorer} from "./@orbitmines/explorer/debug/DebugCanvas"; export const Router = () => { @@ -27,6 +28,9 @@ export const Router = () => { } /> + } /> + {/*} />*/} + } /> @@ -34,8 +38,6 @@ export const Router = () => { - } /> - } /> } /> } /> From cc5e1d57ff3c821aa5255132a63f9c4aaf955680 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 11 Jan 2024 15:36:54 +0100 Subject: [PATCH 050/138] 2024/01/11 - Debug playground setup --- .../explorer/OrbitMinesExplorer.tsx | 2 +- src/@orbitmines/explorer/Ray.ts | 41 ++++++++++++++++--- .../explorer/debug/DebugCanvas.tsx | 39 ++++++++---------- 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index 4b55748..2105fd5 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -100,7 +100,7 @@ export const Line = ({ start, mid, end, scale, color = line.color }: any) => lineWidth={line.width * scale} /> -const circle = { radius: 3, color: "orange", segments: 30, } +export const circle = { radius: 3, color: "orange", segments: 30, } export const Vertex = ({ position, color = circle.color }: any) => diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 5c21fe5..a70e010 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,5 +1,6 @@ import _ from "lodash"; import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; +import {InterfaceOptions} from "./OrbitMinesExplorer"; // SHOULDNT CLASSIFY THESE? @@ -480,25 +481,55 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? //TODO USED FOR DEBUG NOW - move = (func: (self: Ray) => Ray, traversed: Ray[]): Ray => { + move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { const target_ray = func(this.self); const target = target_ray.as_reference().o({ ...this._dirty_store, position: target_ray.any.position ?? this.self.any.position - ?? [0, 0, 0] + ?? Ray.POSITION_OF_DOOM }); console.log('move', `${this.self.label.split(' ')[0]} -> ${target.self.label.split(' ')[0]}`); - if (!target_ray.any.traversed) { - traversed.push(target); - target_ray.any.traversed = true; + if (memory) { + if (!target_ray.any.traversed) { + Interface.any.rays.push(target); + target_ray.any.traversed = true; + } + } else { + Interface.any.rays = [target]; } return target; } + static POSITION_OF_DOOM = [0, 300, 0] + + // TODO: Abstract away as compilation + get render_options(): Required { + return ({ + position: + this.self.any.position + ?? (this.is_none() ? Ray.POSITION_OF_DOOM : [0, 0, 0]), + rotation: + this.self.any.rotation + ?? [0, 0, 0], + scale: + this.self.any.scale + ?? (this.is_none() ? 1.5 : 1.5), + color: + this.self.any.color + ?? (this.is_none() ? 'red' : { + [RayType.VERTEX]: 'orange', + [RayType.TERMINAL]: '#FF5555', + [RayType.INITIAL]: '#5555FF', + [RayType.REFERENCE]: '#555555', + }[this.type] + ) + }); + } + debug = (c: DebugResult): DebugRay => { if (c[this.label] !== undefined) return c[this.label]!; diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index aecd5be..18b2c9d 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -7,7 +7,7 @@ import { _Continuation, _Vertex, add, AutoRay, - AutoVertex, + AutoVertex, circle, InterfaceOptions, Line, SimpleRenderedRay, @@ -31,12 +31,14 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { } = useThree(); const space_between = 20 * scale; + + const memory = true; const [Interface] = useState(Ray.vertex().o({ selection: Ray - .vertex().o({ position: [0, 0, 0], scale, color: 'orange' }) - .initial.o({ position: [-space_between, 0, 0] }).terminal - .terminal.o({ position: [space_between, 0, 0 ]}).initial + .vertex().o({ position: [0, 0, 0], scale, color: '#FF55FF' }) + .initial.o({ position: [-space_between, 0, 0], scale }).terminal + .terminal.o({ position: [space_between, 0, 0 ], scale }).initial .as_reference().o({ position: [0, 0, 0], scale, @@ -49,17 +51,17 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { hotkeys: [ { combo: "a", global: true, label: "", onKeyDown: () => { - Interface.any.selection = Interface.any.selection.move((self: Ray) => self.initial, Interface.any.rays); + Interface.any.selection = Interface.any.selection.move((self: Ray) => self.initial, memory, Interface); } }, { combo: "d", global: true, label: "", onKeyDown: () => { - Interface.any.selection = Interface.any.selection.move((self: Ray) => self.terminal, Interface.any.rays); + Interface.any.selection = Interface.any.selection.move((self: Ray) => self.terminal, memory, Interface); } }, { combo: "w", global: true, label: "", onKeyDown: () => { - Interface.any.selection = Interface.any.selection.move((self: Ray) => self.self, Interface.any.rays); + Interface.any.selection = Interface.any.selection.move((self: Ray) => self.self, memory, Interface); } }, { @@ -83,32 +85,23 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { hotkeyConfig.set(...hotkeys); - const render: { [TKey in keyof InterfaceOptions]: (ray: Ray) => InterfaceOptions[TKey] } = { - position: (ray: Ray) => ray.self.any.position ?? (ray.is_none() ? [0, 400, 0] : [0, 0, 0]), - rotation: (ray: Ray) => ray.self.any.rotation ?? [0, 0, 0], - scale: (ray: Ray): number => ray.self.any.scale ?? (ray.is_none() ? 1.5 : 1.5), - color: (ray: Ray): string => ray.self.any.color ?? (ray.is_none() ? 'red' : 'orange'), - } - - const options = (ray: Ray): Required => _.mapValues(render, (func: any) => func(ray)) as Required; - const Render = ({ ray }: { ray: Ray }) => { - const initial: Required = options(ray.self.initial.as_reference()); - const vertex: Required = options(ray); - const terminal: Required = options(ray.self.terminal.as_reference()); + const initial: Required = ray.self.initial.as_reference().render_options; + const vertex: Required = ray.render_options; + const terminal: Required = ray.self.terminal.as_reference().render_options; switch (ray.type) { case RayType.REFERENCE: - return + return case RayType.INITIAL: { return <> - + <_Continuation {...vertex} /> } case RayType.TERMINAL: { return <> - + <_Continuation {...vertex} /> } @@ -121,7 +114,7 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { return <> {Interface.any.stats ? : <>} - + {/*{Interface.any.rays.map((ray: Ray) => )}*/} {Interface.any.rays.map((ray: Ray) => )} From 8d79a18fb123d2ff727206b909a714612bad86a6 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 11 Jan 2024 15:47:59 +0100 Subject: [PATCH 051/138] 2024/01/11 - List hotkey.combo --- .../explorer/debug/DebugCanvas.tsx | 6 ++--- src/@orbitmines/js/react/hooks/useHotkeys.ts | 26 ++++++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index 18b2c9d..88cc445 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -50,17 +50,17 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { controls: Ray.vertex().o({ hotkeys: [ { - combo: "a", global: true, label: "", onKeyDown: () => { + combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { Interface.any.selection = Interface.any.selection.move((self: Ray) => self.initial, memory, Interface); } }, { - combo: "d", global: true, label: "", onKeyDown: () => { + combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { Interface.any.selection = Interface.any.selection.move((self: Ray) => self.terminal, memory, Interface); } }, { - combo: "w", global: true, label: "", onKeyDown: () => { + combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { Interface.any.selection = Interface.any.selection.move((self: Ray) => self.self, memory, Interface); } }, diff --git a/src/@orbitmines/js/react/hooks/useHotkeys.ts b/src/@orbitmines/js/react/hooks/useHotkeys.ts index d471664..d1fd08e 100755 --- a/src/@orbitmines/js/react/hooks/useHotkeys.ts +++ b/src/@orbitmines/js/react/hooks/useHotkeys.ts @@ -2,19 +2,22 @@ import IModule, {useModule} from "../IModule"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import {useHotkeys as useBlueprintJSHotkeys} from '@blueprintjs/core'; import {useState} from "react"; +import _ from "lodash"; + +export type HotkeyConfigMod = HotkeyConfig & { combo: string | string[] } export const HOTKEYS_MODULE = 'hotkeys'; export type IHotkeysModule = IModule & { reset: () => void, - add: (...hotkeys: HotkeyConfig[]) => void, - set: (...hotkeys: HotkeyConfig[]) => void, - all: () => HotkeyConfig[], + add: (...hotkeys: HotkeyConfigMod[]) => void, + set: (...hotkeys: HotkeyConfigMod[]) => void, + all: () => HotkeyConfigMod[], } export const useHotkeys = (): IHotkeysModule => useModule(HOTKEYS_MODULE) as IHotkeysModule; -export const useHotkeysModule = (...initialHotkeys: HotkeyConfig[]): IHotkeysModule => { +export const useHotkeysModule = (...initialHotkeys: HotkeyConfigMod[]): IHotkeysModule => { const [hotkeys, setHotkeys] = useState(initialHotkeys ?? []); // Hotkeys: https://blueprintjs.com/docs/#core/hooks/use-hotkeys @@ -22,12 +25,21 @@ export const useHotkeysModule = (...initialHotkeys: HotkeyConfig[]): IHotkeysMod showDialogKeyCombo: "?", }); + const setHotKeysMod = (hotkeys: HotkeyConfigMod[]): void => setHotkeys( + hotkeys.flatMap(hotkey => + !_.isArray(hotkey.combo) ? hotkey : hotkey.combo.map( + combo => {...hotkey, combo} + ) + ) + ) + + const module: IHotkeysModule = { identifier: HOTKEYS_MODULE, - reset: () => setHotkeys(initialHotkeys), - add: (...added: HotkeyConfig[]) => setHotkeys([...hotkeys, ...added]), - set: (...hotkeys: HotkeyConfig[]) => setHotkeys([...hotkeys]), + reset: () => setHotKeysMod(initialHotkeys), + add: (...added: HotkeyConfigMod[]) => setHotKeysMod([...hotkeys, ...added]), + set: (...hotkeys: HotkeyConfigMod[]) => setHotKeysMod([...hotkeys]), all: () => hotkeys, onKeyDown, From 5d80b4c97358b90f20a48c78262563e89a48cc83 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 11 Jan 2024 16:26:47 +0100 Subject: [PATCH 052/138] 2024/01/11 - Setting up debug --- .../explorer/OrbitMinesExplorer.tsx | 26 +++--- src/@orbitmines/explorer/Ray.ts | 2 +- .../explorer/debug/DebugCanvas.tsx | 81 +++++++++---------- 3 files changed, 51 insertions(+), 58 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index 2105fd5..77c0e82 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -312,32 +312,26 @@ export const AutoVertex = (ray: Omit & InterfaceOptions & { ..._.pick(ray, 'position', 'rotation', 'scale', 'color') } - const initial: Required = { ..._default, position: [-20 * _default.scale, 0, 0], ...ray.initial }; + const initial: Required = {..._default, position: [-20 * _default.scale, 0, 0], ...ray.initial}; // Vertex as the origin for rotation - const vertex: Required = { ..._default, position: [0, 0, 0] } //, ...ray.vertex }; - const terminal: Required = { ..._default, position: [20 * _default.scale, 0, 0], ...ray.terminal }; + const vertex: Required = {..._default, position: [0, 0, 0]} //, ...ray.vertex }; + const terminal: Required = {..._default, position: [20 * _default.scale, 0, 0], ...ray.terminal}; if (length > 1) // TODO, currently rotates around each vertex individually return {[...Array(length)] - .map(((_, i) => ))} + .map(((_, i) => ))} - const Group = ({ children }: Children) => { - return - {children} - - } - - return - - - + return + + + {children} - + } -export const _Continuation = ({ color = torus.color, ...options }: InterfaceOptions) => +export const _Continuation = ({color = torus.color, ...options }: InterfaceOptions) => { diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index 88cc445..ab9d93f 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -3,21 +3,38 @@ import {VisualizationCanvas} from "../Visualization"; import React, {useEffect, useReducer, useRef, useState} from "react"; import {useHotkeys} from "../../js/react/hooks/useHotkeys"; import {Ray, RayType} from "../Ray"; -import { - _Continuation, _Vertex, - add, - AutoRay, - AutoVertex, circle, - InterfaceOptions, - Line, - SimpleRenderedRay, - torus -} from "../OrbitMinesExplorer"; +import {_Continuation, _Vertex, add, AutoVertex, circle, InterfaceOptions, Line, torus} from "../OrbitMinesExplorer"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import {useThree} from "@react-three/fiber"; import {Stats, StatsGl} from "@react-three/drei"; import _ from "lodash"; -import {NotImplementedError} from "../errors/errors"; + +// TODO: Could be a function on Ray (any func really) +const Render = ({ ray }: { ray: Ray }) => { + const initial: Required = ray.self.initial.as_reference().render_options; + const vertex: Required = ray.render_options; + const terminal: Required = ray.self.terminal.as_reference().render_options; + + switch (ray.type) { + case RayType.REFERENCE: + return + case RayType.INITIAL: { + return <> + + <_Continuation {...vertex} /> + + } + case RayType.TERMINAL: { + return <> + + <_Continuation {...vertex} /> + + } + case RayType.VERTEX: { + return <_Vertex {...vertex} /> + } + } +} const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { const ref = useRef(); @@ -64,8 +81,19 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { Interface.any.selection = Interface.any.selection.move((self: Ray) => self.self, memory, Interface); } }, + // { + // combo: ["s", "arrowdown"], global: true, label: "", onKeyDown: () => { + // Interface.any.selection = Interface.any.selection.move((self: Ray) => self.as_reference().as_reference(), memory, Interface); + // } + // }, { combo: "/", global: true, label: "", onKeyDown: () => { + console.log(`rays.length at pos=[${Interface.any.selection.render_options.position}]: ${Interface.any.rays.filter((ray: Ray) => + _.isEqual( + Interface.any.selection.render_options.position, + ray.render_options.position + ) + ).length} / ${Interface.any.rays.length}`) console.log('ref', Interface.any.selection) console.log('ref.self', Interface.any.selection.self) } @@ -80,36 +108,7 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { }) })); - const { selection, controls, rays } = Interface.any; - const { hotkeys } = controls.any; - - hotkeyConfig.set(...hotkeys); - - const Render = ({ ray }: { ray: Ray }) => { - const initial: Required = ray.self.initial.as_reference().render_options; - const vertex: Required = ray.render_options; - const terminal: Required = ray.self.terminal.as_reference().render_options; - - switch (ray.type) { - case RayType.REFERENCE: - return - case RayType.INITIAL: { - return <> - - <_Continuation {...vertex} /> - - } - case RayType.TERMINAL: { - return <> - - <_Continuation {...vertex} /> - - } - case RayType.VERTEX: { - return <_Vertex {...vertex} /> - } - } - } + hotkeyConfig.set(...Interface.any.controls.any.hotkeys); return <> {Interface.any.stats ? : <>} From c33942cd57f3ab69695974e6994d7b8f09094a4d Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 11 Jan 2024 17:30:33 +0100 Subject: [PATCH 053/138] 2024/01/11 - Setting up debug --- src/@orbitmines/explorer/debug/DebugCanvas.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index ab9d93f..bfc4961 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -2,7 +2,7 @@ import IEventListener from "../../js/react/IEventListener"; import {VisualizationCanvas} from "../Visualization"; import React, {useEffect, useReducer, useRef, useState} from "react"; import {useHotkeys} from "../../js/react/hooks/useHotkeys"; -import {Ray, RayType} from "../Ray"; +import {DebugResult, Ray, RayType} from "../Ray"; import {_Continuation, _Vertex, add, AutoVertex, circle, InterfaceOptions, Line, torus} from "../OrbitMinesExplorer"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import {useThree} from "@react-three/fiber"; @@ -88,6 +88,8 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { // }, { combo: "/", global: true, label: "", onKeyDown: () => { + console.log('---------') + console.log(`Debugging: ${Interface.any.selection.self.label} (type=${Interface.any.selection.type})`) console.log(`rays.length at pos=[${Interface.any.selection.render_options.position}]: ${Interface.any.rays.filter((ray: Ray) => _.isEqual( Interface.any.selection.render_options.position, @@ -96,6 +98,13 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { ).length} / ${Interface.any.rays.length}`) console.log('ref', Interface.any.selection) console.log('ref.self', Interface.any.selection.self) + + const debug: DebugResult = {}; + Interface.any.selection.self.debug(debug); + console.log('ref.debug', debug); + Interface.any.rays.forEach((ray: Ray) => ray.debug(debug)); + console.log('rays.debug', debug); + } }, { From 3e6fdbad2d86bd8c7df91283495f6622ebee859b Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 11 Jan 2024 21:16:20 +0100 Subject: [PATCH 054/138] 2024/01/11 - Setting up debug - Need some better infrastructure for this --- .../explorer/OrbitMinesExplorer.tsx | 2 + src/@orbitmines/explorer/Ray.ts | 36 +++++++++- .../explorer/debug/DebugCanvas.tsx | 66 ++++++++++++++----- 3 files changed, 87 insertions(+), 17 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index 77c0e82..c974b4b 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -7,7 +7,9 @@ import IEventListener from "../js/react/IEventListener"; import {Children} from "../../lib/typescript/React"; import {NotImplementedError} from "./errors/errors"; +// TODO, All this should be automatic through Ray export const add = (a: number[], b: number[]): [number, number, number] => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; +export const sub = (a: number[], b: number[]): [number, number, number] => [a[0] - b[0], a[1] - b[1], a[2] - b[2]]; export const torus = { // Radius of the torus, from the center of the torus to the center of the tube. Default is 1. diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 8ab5595..3724a81 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -142,7 +142,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? is_some = (): boolean => !this.is_none(); - /** [ ] */ static None = () => new Ray({ }); + /** [ ] */ static None = () => new Ray({ }).o({ }); /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { // /** [?????] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }); // /** [?????] -> [??? ] */ as_terminal = () => @@ -455,6 +455,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return this; } + // All these are dirty + o2 = ({ initial, vertex, terminal }: any): Ray => { + if (initial) this.initial.o(initial); + if (vertex) this.o(vertex); + if (terminal) this.terminal.o(terminal); + + return this; + } + protected property = (property: string | symbol, _default?: any): any => this.any[property] ??= (_default ?? Ray.None()); // TODO: Can this be prettier?? protected _proxy: any; @@ -479,10 +488,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }) as T; } + get delete(): Ray { + this.self = Ray.None; // TODO; I made a lazy delete comment somewhere? + return this; + } //TODO USED FOR DEBUG NOW move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { const target_ray = func(this.self); + const target = target_ray.as_reference().o({ ...this._dirty_store, position: @@ -511,7 +525,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return ({ position: this.self.any.position - ?? (this.is_none() ? Ray.POSITION_OF_DOOM : [0, 0, 0]), + ?? (this.is_none() ? Ray.POSITION_OF_DOOM : Ray.POSITION_OF_DOOM), rotation: this.self.any.rotation ?? [0, 0, 0], @@ -530,6 +544,24 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }); } + ___dirty_all(c: Ray[]): Ray[] { + if (c.filter(a => a.label === this.label).length !== 0) { + return c; + } + + c.push(this); + + if (this.initial.as_reference().is_some()) + this.initial.___dirty_all(c); + if (this.vertex.as_reference().is_some()) + this.vertex.___dirty_all(c); + if (this.terminal.as_reference().is_some()) + this.terminal.___dirty_all(c); + + return c; + } + + // TODO: DOESNT DO ON .SELF debug = (c: DebugResult): DebugRay => { if (c[this.label] !== undefined) return c[this.label]!; diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index bfc4961..0df7407 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -17,18 +17,20 @@ const Render = ({ ray }: { ray: Ray }) => { switch (ray.type) { case RayType.REFERENCE: - return + return <_Vertex position={vertex.position} rotation={[0, 0, Math.PI / 2]} scale={vertex.scale / 2} color="#555555" /> case RayType.INITIAL: { - return <> + + return <_Continuation {...vertex} /> - + } case RayType.TERMINAL: { - return <> + // TODO; Rotation like this will not be picked up upon by other thing, calculate on the fly?? + return <_Continuation {...vertex} /> - + } case RayType.VERTEX: { return <_Vertex {...vertex} /> @@ -52,16 +54,20 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { const memory = true; const [Interface] = useState(Ray.vertex().o({ - selection: Ray - .vertex().o({ position: [0, 0, 0], scale, color: '#FF55FF' }) - .initial.o({ position: [-space_between, 0, 0], scale }).terminal - .terminal.o({ position: [space_between, 0, 0 ], scale }).initial - .as_reference().o({ - position: [0, 0, 0], - scale, - rotation: [0, 0, Math.PI / 6 ], - color: '#555555' - }), + selection: Ray.vertex(() => Ray.vertex().o2({ + initial: { position: [-space_between, 0, 0], scale, rotation: [0, 0, Math.PI / 2] }, + vertex: { position: [0, 0, 0], scale, color: '#FF55FF' }, + terminal: { position: [space_between, 0, 0 ], scale, rotation: [0, 0, Math.PI / 2] } + })).o2({ + initial: { position: [-space_between, 0, 0], scale }, + vertex: { position: [0, 0, 0], scale, color: '#FF55FF' }, + terminal: { position: [space_between, 0, 0 ], scale } + }).as_reference().o({ + position: [0, 0, 0], + scale, + rotation: [0, 0, Math.PI / 6 ], + color: '#555555' + }), rays: [] as Ray[], stats: false, controls: Ray.vertex().o({ @@ -76,11 +82,38 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { Interface.any.selection = Interface.any.selection.move((self: Ray) => self.terminal, memory, Interface); } }, + { + combo: ["delete"], global: true, label: "", onKeyDown: () => { + Interface.any.rays = Interface.any.rays.filter((ray: Ray) => ray.self.label !== Interface.any.selection.self.label); // Should be automatic, this sort of thing + Interface.any.selection = Interface.any.selection.delete; + } + }, { combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { + // TODO SHOULD BE ANOTHER DIRECTION AT THE FRAME? Interface.any.selection = Interface.any.selection.move((self: Ray) => self.self, memory, Interface); } }, + { + combo: ["e"], global: true, label: "", onKeyDown: () => { + const change = [0, 0, Math.PI / 10]; + console.log(Interface.any.selection.self.initial.label) + + Interface.any.selection = Interface.any.selection.self.o2({ + initial: { rotation: add(Interface.any.selection.self.initial.any.rotation ?? [0, 0, 0], change) }, + terminal: { rotation: add(Interface.any.selection.self.terminal.any.rotation ?? [0, 0, 0], change) }, + }) + } + }, + { + combo: ["space"], global: true, label: "", onKeyDown: (e) => { + e.preventDefault(); + Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.any.traversed = true; + return ray.as_reference(); + }); + } + }, // { // combo: ["s", "arrowdown"], global: true, label: "", onKeyDown: () => { // Interface.any.selection = Interface.any.selection.move((self: Ray) => self.as_reference().as_reference(), memory, Interface); @@ -117,7 +150,10 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { }) })); + // useEffect(() => { + // TODO: Eventually goes over maximum size of react-debug callstack when updates each frame like this. hotkeyConfig.set(...Interface.any.controls.any.hotkeys); + // }, [Interface.any.controls.any.hotkeys]); return <> {Interface.any.stats ? : <>} From e275e25f910ae8e1e1a46dbbe9f23794124716bb Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 11 Jan 2024 21:57:26 +0100 Subject: [PATCH 055/138] 2024/01/11 - Setting up debug - Need some better infrastructure for this --- src/@orbitmines/explorer/debug/DebugCanvas.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index 0df7407..6824746 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -9,6 +9,9 @@ import {useThree} from "@react-three/fiber"; import {Stats, StatsGl} from "@react-three/drei"; import _ from "lodash"; +// TODO: What about showing disconnect when multiple things are rendered at the same position?? +// TODO: It's, rende rboth draw equivalence, then ignore the difference from either perspective or take some middle thing. - Line from both ends, also vertex? (or take the pos, take the x from one/other, y from the other/..) + // TODO: Could be a function on Ray (any func really) const Render = ({ ray }: { ray: Ray }) => { const initial: Required = ray.self.initial.as_reference().render_options; From 2a0fadf753d45ea972ba45ff824e234383fcc9f6 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Fri, 12 Jan 2024 12:28:07 +0100 Subject: [PATCH 056/138] 2024/01/12 - Testing some debug settings --- src/@orbitmines/explorer/Ray.ts | 48 +- .../explorer/debug/DebugCanvas.tsx | 20 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 445 ++++++++++-------- 3 files changed, 299 insertions(+), 214 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 3724a81..eb3f3f8 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -3,7 +3,7 @@ import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; -// SHOULDNT CLASSIFY THESE? +// TODO: SHOULDNT CLASSIFY THESE? export enum RayType { // NONE = ' ', REFERENCE = ' | ', @@ -190,14 +190,14 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? throw new PreventsImplementationBug(); } case RayType.VERTEX: { - const next_vertex = Ray.vertex(b.as_arbitrary()); // TODO: Could be a reference too, now just force as a next element + // const next_vertex = b; // TODO: Could be a reference too, now just force as a next element if (this.is_none()) { // 'Empty' vertex from this perspective. - this.vertex = next_vertex.as_arbitrary(); + this.vertex = b.as_arbitrary(); console.log('first element'); - return next_vertex.as_reference(); // TODO: Generally, return something which knows where all continuations are. + return b; // TODO: Generally, return something which knows where all continuations are. } switch (b.type) { @@ -212,7 +212,45 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } } - return next_vertex.as_reference(); + return b; + } + } + } + + pop = (): Ray => { + switch (this.type) { + case RayType.REFERENCE: { + throw new PreventsImplementationBug(); + } + case RayType.TERMINAL: + case RayType.INITIAL: { + throw new PreventsImplementationBug(); + } + case RayType.VERTEX: { + const previous_vertex = this.self.initial.self.initial.as_reference(); + + if (this.is_none()) { + return this; // TODO; Already empty, perhaps throw + } + + switch (previous_vertex.type) { + case RayType.REFERENCE: { + throw new PreventsImplementationBug(); + } + case RayType.INITIAL: { + throw new PreventsImplementationBug(); + } + case RayType.TERMINAL: { + throw new PreventsImplementationBug(); + } + case RayType.VERTEX: { + console.log(previous_vertex) + // TODO: NONHACKY + + previous_vertex.self.terminal = new Ray({ vertex: Ray.None, initial: previous_vertex.self.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() + return previous_vertex; + } + } } } } diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index 6824746..db64a9e 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -13,7 +13,7 @@ import _ from "lodash"; // TODO: It's, rende rboth draw equivalence, then ignore the difference from either perspective or take some middle thing. - Line from both ends, also vertex? (or take the pos, take the x from one/other, y from the other/..) // TODO: Could be a function on Ray (any func really) -const Render = ({ ray }: { ray: Ray }) => { +export const Render = ({ ray }: { ray: Ray }) => { const initial: Required = ray.self.initial.as_reference().render_options; const vertex: Required = ray.render_options; const terminal: Required = ray.self.terminal.as_reference().render_options; @@ -41,7 +41,7 @@ const Render = ({ ray }: { ray: Ray }) => { } } -const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { +export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { const ref = useRef(); const hotkeyConfig = useHotkeys(); @@ -57,11 +57,13 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { const memory = true; const [Interface] = useState(Ray.vertex().o({ - selection: Ray.vertex(() => Ray.vertex().o2({ - initial: { position: [-space_between, 0, 0], scale, rotation: [0, 0, Math.PI / 2] }, - vertex: { position: [0, 0, 0], scale, color: '#FF55FF' }, - terminal: { position: [space_between, 0, 0 ], scale, rotation: [0, 0, Math.PI / 2] } - })).o2({ + selection: Ray.vertex( + // () => Ray.vertex().o2({ + // initial: { position: [-space_between, 0, 0], scale, rotation: [0, 0, Math.PI / 2] }, + // vertex: { position: [0, 0, 0], scale, color: '#FF55FF' }, + // terminal: { position: [space_between, 0, 0 ], scale, rotation: [0, 0, Math.PI / 2] } + // }) + ).o2({ initial: { position: [-space_between, 0, 0], scale }, vertex: { position: [0, 0, 0], scale, color: '#FF55FF' }, terminal: { position: [space_between, 0, 0 ], scale } @@ -168,7 +170,7 @@ const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { } -const StatsPanels = () => { +export const StatsPanels = () => { const [_, forceUpdate] = useReducer((x) => !x, false); const parent = useRef(document.createElement('div')); @@ -192,7 +194,7 @@ const StatsPanels = () => { } -const DebugCanvas = ( +export const DebugCanvas = ( { listeners = [], }: { diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 6e96c8f..7f90bee 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -8,82 +8,198 @@ import {DebugRay, DebugResult, Ray, RayType} from "../../explorer/Ray"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import _ from "lodash"; import {Children} from "../../../lib/typescript/React"; +import {useThree} from "@react-three/fiber"; +import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; // TODO: Put the graphs setc at the top, invis lines, then draw them on hover, and maybe make surrounding stuff less visiable. // TODO: make some function which uses a custom input like position of the interface as the thing which breaks equivalences - ignorances. Basically a custom "equivalency function" // TODO; Key to output javascript compilation targets in console, array, .. etc. - -const Interface = () => { +// const Debug = () => { +// const groups: string[][] = []; +// _.values(debug).forEach(ray => { +// for (let group of groups) { +// if (group.includes(ray.label) || group.includes(ray.vertex)) { +// group.push(...[ray.label, ray.vertex].filter(l => l !== 'None')); +// return; +// } +// } +// +// groups.push([ray.label, ray.vertex].filter(l => l !== 'None')); +// }); +// +// const group = (l: string): string[] => groups.find(group => group.includes(l))!; +// const group_index = (l: string): number => groups.indexOf(group(l)); +// const index_in_group = (l: string): number => group(l).indexOf(l); +// +// +// //TODO: do the same for group in initial/yerminal +// return <> +// {/*
*/} +// {_.values(debug).map(((_ray, index) => { +// let ray = { +// ...debug[_ray.label] +// } +// +// const color = { +// [RayType.VERTEX]: 'orange', +// [RayType.TERMINAL]: '#FF5555', +// [RayType.INITIAL]: '#5555FF', +// [RayType.REFERENCE]: '#555555', +// }[ray.type]; +// +// const group_x = _.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position)).map(position => position[0])[0]; +// // console.log(_.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position))) +// +// ray = { +// ...ray, +// ...({ +// color, +// scale: 1.5, +// // rotation: ray.type == RayType.REFERENCE ? [0, 0, Math.PI / 6] : [0, 0, 0], +// position: [ +// group_x ?? group_index(ray.label) * 20 * 1.5, +// // (index_in_group(ray.label) + group_index(ray.label) + (group_x ? 0: 1)) * 30 * 1.5, +// index * 20 * 1.5, +// 0 +// ] +// } as InterfaceOptions) +// } +// +// debug[_ray.label] = ray; +// +// const _default: Required = { +// position: [0, 0, 0], +// rotation: [0, 0, 0], +// scale: 1, +// color: 'orange', +// ..._.pick(ray, 'position', 'rotation', 'scale', 'color'), +// } +// +// // console.log(ray.label, [ray.initial, ray.vertex, ray.terminal].toString()) +// +// const initial: Required = { ..._default, position: [-20 * _default.scale, 0, 0] }; +// +// // Vertex as the origin for rotation +// const vertex: Required = { ..._default, position: [0, 0, 0] } //, ...ray.vertex }; +// const terminal: Required = { ..._default, position: [20 * _default.scale, 0, 0] }; +// +// const Group = ({ children }: Children) => { +// return +// {children} +// +// } +// +// const None = (options: InterfaceOptions) => (<_Continuation {...options} color="#AA0000" scale={1} />) +// +// const Extreme = ({type}: { type: RayType.INITIAL | RayType.TERMINAL }) => { +// const options = type === RayType.INITIAL ? initial : terminal; +// +// switch (ray.type) { +// case RayType.REFERENCE: +// case RayType.VERTEX: { +// const a = type === RayType.INITIAL ? { terminal: vertex } : { initial: vertex }; +// return ; +// } +// case type: { +// return ; +// } +// case (type === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL): { +// return <> +// } +// } +// } +// +// return +// +// +// +// +// }))} +// +// {groups.map(group => <> +// {group.map(l => )} +// )} +// {/*
*/} +// +// } + +export const DebugInterface2 = ({ scale = 1.5 }: InterfaceOptions) => { const ref = useRef(); const hotkeyConfig = useHotkeys(); - const scale = 1.5; - const i = 20 * scale; - - const cursor: InterfaceOptions = { - scale, - rotation: [0, 0, Math.PI / 6 ], - color: '#555555' - }; - - // TODO: Direct call to rerender on change, now there's lag - - const [Chyp] = useState(Ray.vertex().o({ - selection: Ray - .vertex().o({ position: [0, 0, 0], scale, color: 'orange' }) - .as_reference().o({ - position: [0, 0, 0], - ...cursor - }), + const { + gl: renderer, + camera, + scene, + raycaster + } = useThree(); + + const space_between = 20 * scale; + + const [Interface] = useState(Ray.vertex().o({ + selection: Ray.vertex().o2({ + initial: { position: [-space_between, 0, 0], scale, color: 'orange' }, + vertex: { position: [0, 0, 0], scale, color: 'orange' }, + terminal: { position: [space_between, 0, 0 ], scale, color: 'orange' } + }).as_reference().o({ + position: [0, 0, 0], + scale, + rotation: [0, 0, Math.PI / 6 ], + color: '#555555' + }), rays: [] as Ray[], + stats: false, controls: Ray.vertex().o({ - hotkeys: [ { - combo: "arrowright", global: true, label: "", onKeyDown: () => { - const { selection, rays } = Chyp.any; - - const next = Ray.vertex().as_reference().o({ - position: add(selection.any.position ?? [0, 0, 0], [i * 2, 0, 0]), - scale - }); - selection.continues_with(next); - - // const next2 = Ray.js("A").as_reference().o({ - // position: add(selection.any.position ?? [0, 0, 0], [i * 2, -30, 0]), - // scale - // }); - - Chyp.any.selection = next; - Chyp.any.rays = [...rays, next] - - } - }, + hotkeys: [ { - combo: "arrowleft", global: true, label: "", onKeyDown: () => { - const { selection, rays } = Chyp.any; + combo: "arrowright", global: true, label: "", onKeyDown: () => { + const { selection, rays } = Interface.any; + + const current = Interface.any.selection.render_options + + const next = Ray.vertex().o2({ + initial: { position: add(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, + vertex: { position: add(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, + terminal: { position: add(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } + }).as_reference().o({ + ...selection.as_reference().render_options, + position: add(selection.any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) + }); + + Interface.any.selection = selection.continues_with(next); + Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.any.traversed = true; + return ray.as_reference(); + }); - if (rays.length === 0) + } + }, + { + combo: "arrowleft", global: true, label: "", onKeyDown: () => { + if (Interface.any.rays.length === 0) return; - rays.pop(); + Interface.any.selection = Interface.any.selection.pop(); + Interface.any.selection.self.terminal.o({ + position: add(Interface.any.selection.render_options.position, [space_between, 0, 0]), scale, color: 'orange' + }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. - if (rays.length === 0) { - Chyp.any.selection.any.position = [0, 0, 0] + Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.any.traversed = true; + return ray.as_reference(); + }); + + if (Interface.any.length === 0) { + Interface.any.selection.any.position = [0, 0, 0] return; } - - Chyp.any.selection = rays[rays.length - 1]; - - // selection.continues_with( - - // ); - } }, { combo: "arrowup", global: true, label: "", onKeyDown: () => { - const { selection, rays } = Chyp.any; + const { selection, rays } = Interface.any; - Chyp.any.rays = rays.flatMap((ray: Ray) => [ + Interface.any.rays = rays.flatMap((ray: Ray) => [ ray, // Ray.js("A").as_reference().o({ // // ...ray.o, @@ -109,162 +225,91 @@ const Interface = () => { // ); } - }] as HotkeyConfig[] - }) - })); - - const { selection, controls, rays } = Chyp.any; - const { hotkeys } = controls.any; - - hotkeyConfig.set(...hotkeys); - - const Rendered = ({ ray, ...options }: { ray: Ray } & InterfaceOptions) => { - const { position = options.position, rotation = options.rotation, scale = options.scale, color = options.color } = ray.any; - return ; - } - - const render = () => { - - } - - - const DEBUG = true; - - const debug: DebugResult = {}; - selection.debug(debug); - - const Debug = () => { - const groups: string[][] = []; - _.values(debug).forEach(ray => { - for (let group of groups) { - if (group.includes(ray.label) || group.includes(ray.vertex)) { - group.push(...[ray.label, ray.vertex].filter(l => l !== 'None')); - return; - } - } - - groups.push([ray.label, ray.vertex].filter(l => l !== 'None')); - }); - - const group = (l: string): string[] => groups.find(group => group.includes(l))!; - const group_index = (l: string): number => groups.indexOf(group(l)); - const index_in_group = (l: string): number => group(l).indexOf(l); - - - //TODO: do the same for group in initial/yerminal - return <> - {/*
*/} - {_.values(debug).map(((_ray, index) => { - let ray = { - ...debug[_ray.label] - } - - const color = { - [RayType.VERTEX]: 'orange', - [RayType.TERMINAL]: '#FF5555', - [RayType.INITIAL]: '#5555FF', - [RayType.REFERENCE]: '#555555', - }[ray.type]; - - const group_x = _.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position)).map(position => position[0])[0]; - // console.log(_.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position))) - - ray = { - ...ray, - ...({ - color, - scale: 1.5, - // rotation: ray.type == RayType.REFERENCE ? [0, 0, Math.PI / 6] : [0, 0, 0], - position: [ - group_x ?? group_index(ray.label) * 20 * 1.5, - // (index_in_group(ray.label) + group_index(ray.label) + (group_x ? 0: 1)) * 30 * 1.5, - index * 20 * 1.5, - 0 - ] - } as InterfaceOptions) - } - - debug[_ray.label] = ray; - - const _default: Required = { - position: [0, 0, 0], - rotation: [0, 0, 0], - scale: 1, - color: 'orange', - ..._.pick(ray, 'position', 'rotation', 'scale', 'color'), - } - - // console.log(ray.label, [ray.initial, ray.vertex, ray.terminal].toString()) - - const initial: Required = { ..._default, position: [-20 * _default.scale, 0, 0] }; - - // Vertex as the origin for rotation - const vertex: Required = { ..._default, position: [0, 0, 0] } //, ...ray.vertex }; - const terminal: Required = { ..._default, position: [20 * _default.scale, 0, 0] }; + }, + { + combo: "/", global: true, label: "", onKeyDown: () => { + console.log('---------') + console.log(`Debugging: ${Interface.any.selection.self.label} (type=${Interface.any.selection.type})`) + console.log(`rays.length at pos=[${Interface.any.selection.render_options.position}]: ${Interface.any.rays.filter((ray: Ray) => + _.isEqual( + Interface.any.selection.render_options.position, + ray.render_options.position + ) + ).length} / ${Interface.any.rays.length}`) + console.log('ref', Interface.any.selection) + console.log('ref.self', Interface.any.selection.self) + + const debug: DebugResult = {}; + Interface.any.selection.self.debug(debug); + console.log('ref.debug', debug); + Interface.any.rays.forEach((ray: Ray) => ray.debug(debug)); + console.log('rays.debug', debug); - const Group = ({ children }: Children) => { - return - {children} - } - - const None = (options: InterfaceOptions) => (<_Continuation {...options} color="#AA0000" scale={1} />) - - const Extreme = ({type}: { type: RayType.INITIAL | RayType.TERMINAL }) => { - const options = type === RayType.INITIAL ? initial : terminal; - - switch (ray.type) { - case RayType.REFERENCE: - case RayType.VERTEX: { - const a = type === RayType.INITIAL ? { terminal: vertex } : { initial: vertex }; - return ; - } - case type: { - return ; - } - case (type === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL): { - return <> - } - } + }, + { + combo: "f3", global: true, label: "Show stats Panel", onKeyDown: (e) => { + e.preventDefault(); + Interface.any.stats = !Interface.any.stats; } + }, + ] as HotkeyConfig[] + }) + })); - return - - - - - }))} - - {groups.map(group => <> - {group.map(l => )} - )} - {/*
*/} - - } + // useEffect(() => { + // TODO: Eventually goes over maximum size of react-debug callstack when updates each frame like this. + hotkeyConfig.set(...Interface.any.controls.any.hotkeys); + // }, [Interface.any.controls.any.hotkeys]); return <> -
- {/**/} - {/**/} - {/**/} - - {/**/} + {Interface.any.stats ? : <>} - {/**/} - {/**/} - - + - {rays.map((ray: Ray) => )} + {/*{Interface.any.rays.map((ray: Ray) => )}*/} + {Interface.any.rays.map((ray: Ray) => )} - - - - {/**/} -
+ + {/**/} + } +// const Interface = () => { +// // TODO: Direct call to rerender on change, now there's lag +// +// const Rendered = ({ ray, ...options }: { ray: Ray } & InterfaceOptions) => { +// const { position = options.position, rotation = options.rotation, scale = options.scale, color = options.color } = ray.any; +// return ; +// } +// +// const DEBUG = true; +// +// const debug: DebugResult = {}; +// selection.debug(debug); +// +// return <> +//
+// {/**/} +// {/**/} +// {/**/} +// +// {/**/} +// +// {/**/} +// {/**/} +// +// +// +// {rays.map((ray: Ray) => )} +// +// {/**/} +//
+// +// } + /** * TODO: Import .chyp files * TODO: Export to .chyp files @@ -289,7 +334,7 @@ const ChypCanvas = ( - + } From fd5b92f6273b050f503e0054ad888d5ed37d1859 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Fri, 12 Jan 2024 14:23:04 +0100 Subject: [PATCH 057/138] 2024/01/12 - Some examples --- .../explorer/OrbitMinesExplorer.tsx | 7 + src/@orbitmines/external/chyp/ChypCanvas.tsx | 202 ++++++++++++++++-- 2 files changed, 191 insertions(+), 18 deletions(-) diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index c974b4b..5dd58ee 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -8,6 +8,13 @@ import {Children} from "../../lib/typescript/React"; import {NotImplementedError} from "./errors/errors"; // TODO, All this should be automatic through Ray +export const add_ = (...a: number[][]): [number, number, number] => { + let res = a[0]; + for (let i = 1; i < a.length; i++) { + res = add(res, a[i]); + } + return res as [number, number, number]; +} export const add = (a: number[], b: number[]): [number, number, number] => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; export const sub = (a: number[], b: number[]): [number, number, number] => [a[0] - b[0], a[1] - b[1], a[2] - b[2]]; diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 7f90bee..b07d931 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -1,13 +1,21 @@ import React, {useRef, useState} from "react"; import IEventListener from "../../js/react/IEventListener"; import {VisualizationCanvas} from "../../explorer/Visualization"; -import {_Continuation, add, AutoVertex, InterfaceOptions, SimpleRenderedRay} from "../../explorer/OrbitMinesExplorer"; -import {Center} from "@react-three/drei"; +import { + _Continuation, + _Vertex, + add, + add_, + AutoVertex, + circle, + InterfaceOptions, + Line, + torus +} from "../../explorer/OrbitMinesExplorer"; import {useHotkeys} from "../../js/react/hooks/useHotkeys"; -import {DebugRay, DebugResult, Ray, RayType} from "../../explorer/Ray"; +import {DebugResult, Ray, RayType} from "../../explorer/Ray"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import _ from "lodash"; -import {Children} from "../../../lib/typescript/React"; import {useThree} from "@react-three/fiber"; import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; @@ -123,7 +131,112 @@ import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; // // } -export const DebugInterface2 = ({ scale = 1.5 }: InterfaceOptions) => { +const ___index = (ray: Ray): number => { + switch (ray.type) { + case RayType.REFERENCE: + return ray.self.any.index ?? 0; + case RayType.INITIAL: + return ray.self.terminal.any.index ?? 0; + case RayType.TERMINAL: + return ray.self.initial.any.index ?? 0; + case RayType.VERTEX: + return ray.self.any.index ?? 0; + } +} + +export const Render2 = ({ ray, show = { initial: true, terminal: true } }: { ray: Ray, index: number, show?: { initial: boolean, terminal: boolean } }) => { + const index = ___index(ray); + let added = [15 * index, 60 * index, 0]; + + const initial: Required = ray.self.initial.as_reference().render_options; + initial.position = add_(initial.position, added); + const vertex: Required = ray.render_options; + vertex.position = add_(vertex.position, added); + const terminal: Required = ray.self.terminal.as_reference().render_options; + terminal.position = add_(terminal.position, added); + + switch (ray.type) { + case RayType.REFERENCE: + return <_Vertex position={vertex.position} rotation={[0, 0, Math.PI / 2]} scale={vertex.scale / 2} color="#555555" /> + case RayType.INITIAL: { + const diff = [-15, -15, 0]; + + return + {!show.initial ? : + + + + + + } + + + + + + + + <_Continuation {...vertex} position={add_(vertex.position, !show.initial && ray.type === RayType.INITIAL ? [-15, -15, 0] : [0, 0, 0])} /> + + + {!show.initial ? : + + <_Continuation {...vertex} position={add_(vertex.position, diff)} color="#FF5555"/> + <_Continuation {...vertex} position={add_(vertex.position, diff, [-30, 0, 0])} scale={vertex.scale / 3 * 2} + color="#AA0000"/> + } + + } + case RayType.TERMINAL: { + const diff = [15, 15, 0]; + + return + {!show.terminal ? : + + + + + + + + } + + + + + + <_Continuation {...vertex} position={add_(vertex.position, !show.terminal && ray.type === RayType.TERMINAL ? [15, 15, 0] : [0, 0, 0])} /> + + + {!show.terminal ? : + + <_Continuation {...vertex} position={add_(vertex.position, diff)} color="#5555FF" /> + <_Continuation {...vertex} position={add_(vertex.position, diff, [30, 0, 0])} scale={vertex.scale / 3 * 2} color="#AA0000"/> + } + + } + case RayType.VERTEX: { + return <_Vertex {...vertex} /> + } + } +} + +export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { const ref = useRef(); const hotkeyConfig = useHotkeys(); @@ -139,8 +252,8 @@ export const DebugInterface2 = ({ scale = 1.5 }: InterfaceOptions) => { const [Interface] = useState(Ray.vertex().o({ selection: Ray.vertex().o2({ initial: { position: [-space_between, 0, 0], scale, color: 'orange' }, - vertex: { position: [0, 0, 0], scale, color: 'orange' }, - terminal: { position: [space_between, 0, 0 ], scale, color: 'orange' } + vertex: { index: 0, position: [0, 0, 0], scale, color: 'orange' }, + terminal: { position: [space_between, 0, 0 ], scale, color: 'orange' }, }).as_reference().o({ position: [0, 0, 0], scale, @@ -152,15 +265,15 @@ export const DebugInterface2 = ({ scale = 1.5 }: InterfaceOptions) => { controls: Ray.vertex().o({ hotkeys: [ { - combo: "arrowright", global: true, label: "", onKeyDown: () => { + combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { const { selection, rays } = Interface.any; - const current = Interface.any.selection.render_options + const current = Interface.any.selection.render_options; const next = Ray.vertex().o2({ - initial: { position: add(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, - vertex: { position: add(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, - terminal: { position: add(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } + initial: { position: add_(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, + vertex: { index: Interface.any.selection.self.any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, + terminal: { position: add_(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } }).as_reference().o({ ...selection.as_reference().render_options, position: add(selection.any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) @@ -175,11 +288,14 @@ export const DebugInterface2 = ({ scale = 1.5 }: InterfaceOptions) => { } }, { - combo: "arrowleft", global: true, label: "", onKeyDown: () => { + combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { if (Interface.any.rays.length === 0) return; Interface.any.selection = Interface.any.selection.pop(); + Interface.any.selection.o({ + position: Interface.any.selection.render_options.position + }); // TODO, Same with this. Interface.any.selection.self.terminal.o({ position: add(Interface.any.selection.render_options.position, [space_between, 0, 0]), scale, color: 'orange' }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. @@ -196,7 +312,7 @@ export const DebugInterface2 = ({ scale = 1.5 }: InterfaceOptions) => { } }, { - combo: "arrowup", global: true, label: "", onKeyDown: () => { + combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { const { selection, rays } = Interface.any; Interface.any.rays = rays.flatMap((ray: Ray) => [ @@ -262,17 +378,67 @@ export const DebugInterface2 = ({ scale = 1.5 }: InterfaceOptions) => { hotkeyConfig.set(...Interface.any.controls.any.hotkeys); // }, [Interface.any.controls.any.hotkeys]); + const index = ___index(Interface.any.selection); + const added = [15 * index, 60 * (index + 1), 0]; + return <> {Interface.any.stats ? : <>} - + {/*{Interface.any.rays.map((ray: Ray) => )}*/} + {Interface.any.rays.map((ray: Ray) => )} - - {/**/} + + + + {Interface.any.rays.map((ray: Ray, index: number) => )} + + + {/**/} + {/* */} + {/* */} + {/* {Interface.any.rays.map((ray: Ray, index: number) => )}*/} + {/* */} + {/**/} + + + {[ + Ray.vertex().o2({ + initial: { position: [(-space_between / 1.5) - (space_between / 1.5) * 2, -140, 0], scale: scale / 1.5, color: '#FF5555' }, + vertex: { index: 0, position: [0 - (space_between / 1.5) * 2, -140, 0], scale: scale / 1.5, color: '#FF5555' }, + terminal: { position: [(space_between / 1.5) - (space_between / 1.5) * 2, -140, 0 ], scale: scale / 1.5, color: '#FF5555' }, + }), + Ray.vertex().o2({ + initial: { position: [(-space_between / 1.5) + (space_between / 1.5) * 2, -120, 0], scale: scale / 1.5, color: '#FF5555' }, + vertex: { index: 0, position: [0 + (space_between / 1.5) * 2, -120, 0], scale: scale / 1.5, color: '#FF5555' }, + terminal: { position: [(space_between / 1.5) + (space_between / 1.5) * 2, -120, 0 ], scale: scale / 1.5, color: '#FF5555' }, + }), + Ray.vertex().o2({ + initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' }, + vertex: { index: 0, position: [0, -120, 0], scale: scale / 1.5, color: '#FF5555' }, + terminal: { position: [(space_between / 1.5), -120, 0 ], scale: scale / 1.5, color: '#FF5555' }, + }), + Ray.vertex().o2({ + initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' }, + vertex: { index: 0, position: [0, -140, 0], scale: scale / 1.5, color: '#FF5555' }, + terminal: { position: [(space_between / 1.5), -120, 0 ], scale: scale / 1.5, color: '#FF5555' }, + }), + Ray.vertex().o2({ + initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' }, + vertex: { index: 0, position: [0, -160, 0], scale: scale / 1.5, color: '#FF5555' }, + terminal: { position: [(space_between / 1.5), -160, 0 ], scale: scale / 1.5, color: '#FF5555' }, + }), + ] + .flatMap(ray => [ray.initial.as_reference(), ray.as_reference(), ray.terminal.as_reference()]) + .map(ray => ) + } + {/**/} + {/**/} } From 175e614e1c39b2959018eb7380c5c768dd526dd3 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Fri, 12 Jan 2024 15:39:34 +0100 Subject: [PATCH 058/138] 2024/01/12 - Some examples --- .../explorer/debug/DebugCanvas.tsx | 2 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 83 ++++++++++--------- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index db64a9e..7ba374b 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -54,7 +54,7 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { const space_between = 20 * scale; - const memory = true; + const memory = false; const [Interface] = useState(Ray.vertex().o({ selection: Ray.vertex( diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index b07d931..1d095d9 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -391,13 +391,14 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { {Interface.any.rays.map((ray: Ray) => )} - - - - {Interface.any.rays.map((ray: Ray, index: number) => )} - - + {/**/} + {/* */} + {/* */} + {/* {Interface.any.rays.map((ray: Ray, index: number) => )}*/} + {/* */} + {/**/} + {/**/} {/* */} @@ -406,40 +407,40 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { {/* */} {/**/} - - {[ - Ray.vertex().o2({ - initial: { position: [(-space_between / 1.5) - (space_between / 1.5) * 2, -140, 0], scale: scale / 1.5, color: '#FF5555' }, - vertex: { index: 0, position: [0 - (space_between / 1.5) * 2, -140, 0], scale: scale / 1.5, color: '#FF5555' }, - terminal: { position: [(space_between / 1.5) - (space_between / 1.5) * 2, -140, 0 ], scale: scale / 1.5, color: '#FF5555' }, - }), - Ray.vertex().o2({ - initial: { position: [(-space_between / 1.5) + (space_between / 1.5) * 2, -120, 0], scale: scale / 1.5, color: '#FF5555' }, - vertex: { index: 0, position: [0 + (space_between / 1.5) * 2, -120, 0], scale: scale / 1.5, color: '#FF5555' }, - terminal: { position: [(space_between / 1.5) + (space_between / 1.5) * 2, -120, 0 ], scale: scale / 1.5, color: '#FF5555' }, - }), - Ray.vertex().o2({ - initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' }, - vertex: { index: 0, position: [0, -120, 0], scale: scale / 1.5, color: '#FF5555' }, - terminal: { position: [(space_between / 1.5), -120, 0 ], scale: scale / 1.5, color: '#FF5555' }, - }), - Ray.vertex().o2({ - initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' }, - vertex: { index: 0, position: [0, -140, 0], scale: scale / 1.5, color: '#FF5555' }, - terminal: { position: [(space_between / 1.5), -120, 0 ], scale: scale / 1.5, color: '#FF5555' }, - }), - Ray.vertex().o2({ - initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' }, - vertex: { index: 0, position: [0, -160, 0], scale: scale / 1.5, color: '#FF5555' }, - terminal: { position: [(space_between / 1.5), -160, 0 ], scale: scale / 1.5, color: '#FF5555' }, - }), - ] - .flatMap(ray => [ray.initial.as_reference(), ray.as_reference(), ray.terminal.as_reference()]) - .map(ray => ) - } - {/**/} - {/**/} - + {/**/} + {/* {[*/} + {/* Ray.vertex().o2({*/} + {/* initial: { position: [(-space_between / 1.5) - (space_between / 1.5) * 2, -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* vertex: { index: 0, position: [0 - (space_between / 1.5) * 2, -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* terminal: { position: [(space_between / 1.5) - (space_between / 1.5) * 2, -140, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} + {/* }),*/} + {/* Ray.vertex().o2({*/} + {/* initial: { position: [(-space_between / 1.5) + (space_between / 1.5) * 2, -120, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* vertex: { index: 0, position: [0 + (space_between / 1.5) * 2, -120, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* terminal: { position: [(space_between / 1.5) + (space_between / 1.5) * 2, -120, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} + {/* }),*/} + {/* Ray.vertex().o2({*/} + {/* initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* vertex: { index: 0, position: [0, -120, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* terminal: { position: [(space_between / 1.5), -120, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} + {/* }),*/} + {/* Ray.vertex().o2({*/} + {/* initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* vertex: { index: 0, position: [0, -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* terminal: { position: [(space_between / 1.5), -120, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} + {/* }),*/} + {/* Ray.vertex().o2({*/} + {/* initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* vertex: { index: 0, position: [0, -160, 0], scale: scale / 1.5, color: '#FF5555' },*/} + {/* terminal: { position: [(space_between / 1.5), -160, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} + {/* }),*/} + {/* ]*/} + {/* .flatMap(ray => [ray.initial.as_reference(), ray.as_reference(), ray.terminal.as_reference()])*/} + {/* .map(ray => )*/} + {/* }*/} + {/* /!**!/*/} + {/* /!**!/*/} + {/**/} } From 707a05409708e308682c42f87fc806351ffba38d Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 10:57:10 +0100 Subject: [PATCH 059/138] 2024/01/13 - Setup for arbitrary functions? --- src/@orbitmines/explorer/Ray.ts | 306 ++++++++++--------- src/@orbitmines/external/chyp/ChypCanvas.tsx | 28 +- 2 files changed, 173 insertions(+), 161 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index eb3f3f8..7f7a20e 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -17,19 +17,23 @@ export type Arbitrary = (...args: any[]) => T; export type Constructor = new (...args: any[]) => T; export type ParameterlessConstructor = new () => T; -export function initial() { +// TODO: Merge with Arbitrary. +export type Method = (b?: T, ...other: T[]) => T; +export type ArbitraryMethod = (ref: T) => Method; - return function (target: any, propertyKey: string): any { - Object.defineProperty(target, propertyKey, { - get: (): any => { return target.initial; }, - set: (value) => { - target.initial = value; - }, - // enumerable: true, - // configurable: true - }); - } -} +// export function initial() { +// +// return function (target: any, propertyKey: string): any { +// Object.defineProperty(target, propertyKey, { +// get: (): any => { return target.initial; }, +// set: (value) => { +// target.initial = value; +// }, +// // enumerable: true, +// // configurable: true +// }); +// } +// } /** * https://en.wikipedia.org/wiki/Homoiconicity @@ -174,22 +178,53 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // as_option = (): Ray => Option.Some(this); as_arbitrary = (): Arbitrary => () => this; + // TODO: Should also be abstracted into the Ray + switch = (cases: { + [RayType.REFERENCE]?: string | Arbitrary, + [RayType.INITIAL]?: string | Arbitrary, + [RayType.VERTEX]?: string | Arbitrary, // TODO: Automatic opposite for initial/terminaL?? + [RayType.TERMINAL]?: string | Arbitrary, + }): Ray => { + const _case = cases[this.type]; + + if (_case === undefined || _.isString(_case)) + throw new PreventsImplementationBug(_case ?? '??'); + + return _case(); + } + + continues_with2 = Ray.___func( + + )(this); + + /** + * Constructs a function accepting arbitrary structure based on one implementation of it. + * + * TODO: Is there some equivalent of this in computer science??? category theory?? + * + * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = ... + */ + static ___func = ( + a: any + ): ArbitraryMethod => { + return (ref: Ray): Method => (b?: Ray, ...other: Ray[]): Ray => { + + } + } + // TODO AS += through property continues_with = (b: Ray): Ray => { // TODO: contiues_with is just composing vertices.. - - switch (this.type) { - case RayType.REFERENCE: { - // TODO: We could either go inside the reference and continue there, or expand the direction of reference - // TODO: We could move when a reference is on the vertex, set the type to vertex from the perspective of the reference - throw new PreventsImplementationBug(); - } - case RayType.TERMINAL: - case RayType.INITIAL: { - // TODO: Could be each element found in this direction, or continue *after* the entire direction - throw new PreventsImplementationBug(); - } - case RayType.VERTEX: { + // TODO: Should be: ([this, self_reference, b] as Ray).compose/../merge, dropping this middle vertex, connecting initial/terminal + // TODO: Or otherwise: take everything at the vertex, compose it together??>? + + return this.switch({ + [RayType.REFERENCE]: + "We could either go inside the reference and continue there, or expand the direction of reference." + + "We could move when a reference is on the vertex, set the type to vertex from the perspective of the reference", + [RayType.TERMINAL]: "", + [RayType.INITIAL]: "Could be each element found in this direction, or continue *after* the entire direction", + [RayType.VERTEX]: (): Ray => { // const next_vertex = b; // TODO: Could be a reference too, now just force as a next element if (this.is_none()) { @@ -200,61 +235,121 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return b; // TODO: Generally, return something which knows where all continuations are. } - switch (b.type) { - case RayType.REFERENCE: - case RayType.INITIAL: - case RayType.TERMINAL: { - throw new PreventsImplementationBug(); - } - case RayType.VERTEX: { + return b.switch({ + [RayType.VERTEX]: () => { this.self.terminal.equivalent(b.self.initial); - break; + return b; } - } - - return b; + }); } - } + }); } - pop = (): Ray => { + // zip also compose??? + // [a, b, c] zip [d, e, f] zip [g, h, i] ... + // [[a,d,g],[b,e,h],[c,f,i]] + zip = (): Ray => { throw new NotImplementedError(); } + + /** + * Compose structures defined at .initial with those at .terminal, dropping the vertex. ; or if done non-ignorantly. Composing them on another level, ignoring to this vertex. TODO: Allow this freedom + */ + get merge(): Ray { + // concat initial.a + initial.b, terminal.a + terminal.b + // then: either destroy a/b, merge structure... etc.. + // Chyp: destroy b + + // this.initial.equivalent(other.initial); + // this.terminal.equivalent(other.terminal); + + /* + + vd = self.vertex_data(v) + # print("merging %s <- %s" % (v, w)) + + # Where vertex `w` occurs as an edge target, replace it with `v` + for e in self.in_edges(w): + ed = self.edge_data(e) + ed.t = [v if x == w else x for x in ed.t] + vd.in_edges.add(e) + + # Where vertex `w` occurs as an edge source, replace it with `v` + for e in self.out_edges(w): + ed = self.edge_data(e) + ed.s = [v if x == w else x for x in ed.s] + vd.out_edges.add(e) + + # Wherever `w` occurs on the graph boundary, replace it with `v` + self.set_inputs([v if x == w else x for x in self.inputs]) + self.set_outputs([v if x == w else x for x in self.outputs]) + + # Remove references to `w` from the graph + self.remove_vertex(w) + + */ + throw new NotImplementedError(); + } + // @alias('merge') ?? + get compose(): Ray { switch (this.type) { - case RayType.REFERENCE: { - throw new PreventsImplementationBug(); - } - case RayType.TERMINAL: - case RayType.INITIAL: { - throw new PreventsImplementationBug(); + case RayType.REFERENCE: + case RayType.INITIAL: + case RayType.TERMINAL: { + throw new NotImplementedError(); } case RayType.VERTEX: { - const previous_vertex = this.self.initial.self.initial.as_reference(); + const vertex = this.self; - if (this.is_none()) { - return this; // TODO; Already empty, perhaps throw + // TODO; Implement as restrictive case for Chyp + { + // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) + // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); + + // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. + // if (this.self.initial.is_equivalent(this.self.terminal)) + // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output } - switch (previous_vertex.type) { - case RayType.REFERENCE: { - throw new PreventsImplementationBug(); - } - case RayType.INITIAL: { - throw new PreventsImplementationBug(); - } - case RayType.TERMINAL: { - throw new PreventsImplementationBug(); - } - case RayType.VERTEX: { - console.log(previous_vertex) - // TODO: NONHACKY + /** + * A simple case of what we want to solve here. + * + * Initial Terminal + * ... ... + * [--| ] [ |--] + * [--| ] [ |--] + * [--| ] [ |--] + * [ |--] [--|--] [--| ] + * vertex + * + * And recursively (arbitrarily) match initial/terminal structures. + */ - previous_vertex.self.terminal = new Ray({ vertex: Ray.None, initial: previous_vertex.self.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() - return previous_vertex; - } - } + throw new NotImplementedError(); } } + throw new NotImplementedError(); } + + pop = (): Ray => this.switch({ + [RayType.VERTEX]: () => { + const previous_vertex = this.self.initial.self.initial.as_reference(); + + if (this.is_none()) { + return this; // TODO; Already empty, perhaps throw + } + + return previous_vertex.switch({ + [RayType.VERTEX]: () => { + console.log(previous_vertex) + // TODO: NONHACKY + + previous_vertex.self.terminal = new Ray({ vertex: Ray.None, initial: previous_vertex.self.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() + return previous_vertex; + } + }); + } + }); + /** * next = (): Option => JS.Iterable(this.traverse({ steps: 1 })).as_ray(); * previous = (): Option => JS.Iterable(this.traverse({ steps: 1, direction: { reverse: true } })).as_ray(); @@ -349,89 +444,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? min = (_default: 0): Ray => { throw new NotImplementedError(); } max = (_default: 0): Ray => { throw new NotImplementedError(); } - // [a, b, c] zip [d, e, f] zip [g, h, i] ... - // [[a,d,g],[b,e,h],[c,f,i]] - zip = (): Ray => { throw new NotImplementedError(); } - - /** - * Compose structures defined at .initial with those at .terminal, dropping the vertex. ; or if done non-ignorantly. Composing them on another level, ignoring to this vertex. TODO: Allow this freedom - */ - get merge(): Ray { - // concat initial.a + initial.b, terminal.a + terminal.b - // then: either destroy a/b, merge structure... etc.. - // Chyp: destroy b - - // this.initial.equivalent(other.initial); - // this.terminal.equivalent(other.terminal); - - /* - - vd = self.vertex_data(v) - # print("merging %s <- %s" % (v, w)) - - # Where vertex `w` occurs as an edge target, replace it with `v` - for e in self.in_edges(w): - ed = self.edge_data(e) - ed.t = [v if x == w else x for x in ed.t] - vd.in_edges.add(e) - - # Where vertex `w` occurs as an edge source, replace it with `v` - for e in self.out_edges(w): - ed = self.edge_data(e) - ed.s = [v if x == w else x for x in ed.s] - vd.out_edges.add(e) - - # Wherever `w` occurs on the graph boundary, replace it with `v` - self.set_inputs([v if x == w else x for x in self.inputs]) - self.set_outputs([v if x == w else x for x in self.outputs]) - - # Remove references to `w` from the graph - self.remove_vertex(w) - - */ - throw new NotImplementedError(); - } - // @alias('merge') ?? - get compose(): Ray { - switch (this.type) { - case RayType.REFERENCE: - case RayType.INITIAL: - case RayType.TERMINAL: { - throw new NotImplementedError(); - } - case RayType.VERTEX: { - const vertex = this.self; - - // TODO; Implement as restrictive case for Chyp - { - // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) - // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); - - // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. - // if (this.self.initial.is_equivalent(this.self.terminal)) - // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output - } - - /** - * A simple case of what we want to solve here. - * - * Initial Terminal - * ... ... - * [--| ] [ |--] - * [--| ] [ |--] - * [--| ] [ |--] - * [ |--] [--|--] [--| ] - * vertex - * - * And recursively (arbitrarily) match initial/terminal structures. - */ - - throw new NotImplementedError(); - } - } - throw new NotImplementedError(); - } - // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS apply = (func: Ray) => { diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 1d095d9..0d4401b 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -391,21 +391,21 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { {Interface.any.rays.map((ray: Ray) => )} - {/**/} - {/* */} - {/* */} - {/* {Interface.any.rays.map((ray: Ray, index: number) => )}*/} - {/* */} - {/**/} + + + + {Interface.any.rays.map((ray: Ray, index: number) => )} + + - {/**/} - {/* */} - {/* */} - {/* {Interface.any.rays.map((ray: Ray, index: number) => )}*/} - {/* */} - {/**/} + + + + {Interface.any.rays.map((ray: Ray, index: number) => )} + + {/**/} {/* {[*/} From f523b684c993ba30484c206d2975edb93398e764 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 13:41:12 +0100 Subject: [PATCH 060/138] 2024/01/13 - Method test --- src/@orbitmines/explorer/Ray.spec.ts | 49 +++++++++++--- src/@orbitmines/explorer/Ray.ts | 95 ++++++++++++++++++++-------- 2 files changed, 109 insertions(+), 35 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 2bee84e..49d0bbd 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -1,6 +1,43 @@ import {Ray, RayType} from "./Ray"; describe("Ray", () => { + test(".___func(ref)", () => { + const method = Ray.___func((ref: Ray): Ray => new Ray({ + initial: ref.self.initial.as_arbitrary(), + terminal: ref.self.terminal.as_arbitrary() + }).o({ js: ref.type })); + + expect(method(Ray.vertex().as_reference().as_reference())().any.js).toBe(RayType.REFERENCE); + expect(method(Ray.vertex().as_reference())().any.js).toBe(RayType.VERTEX); + expect(method(Ray.initial().as_reference())().any.js).toBe(RayType.INITIAL); + expect(method(Ray.terminal().as_reference())().any.js).toBe(RayType.TERMINAL); + + const a = Ray.vertex().o({ js: 'A'}).as_reference(); + const b = Ray.vertex().o({ js: 'B'}).as_reference(); + + // TODO What about method(a)(b)(c)... :thinking: + expect(method(a)(b).initial.self.any.js).toBe('A'); + expect(method(a)(b).terminal.self.any.js).toBe('B'); + expect(method(a)(b).type).toBe(RayType.VERTEX); + }); + test(".vertex.#.continues_with(.vertex.#)", () => { + let A = Ray.vertex().o({ js: 'A' }).as_reference(); + let B = Ray.vertex().o({ js: 'B'}).as_reference(); + + B = A.continues_with(B); + + expect(B.type).toBe(RayType.VERTEX); + expect(B.self.any.js).toBe('B'); + expect(B.self + .initial.self.initial + .any.js + ).toBe('A'); + expect(B.self + .initial.self.initial + .terminal.self.terminal + .any.js + ).toBe('B'); + }); // test(".vertex.#.debug", () => { // const a = Ray.vertex().as_reference(); // const b = Ray.vertex().as_reference(); @@ -11,6 +48,9 @@ describe("Ray", () => { // // expect(debug).toEqual('') // }) + test(".as_arbitrary", () => { + expect(Ray.vertex().o({ js: 'A' }).as_arbitrary()().any.js).toBe('A'); + }); test(".o", () => { const ray = Ray.vertex().o({ a: 'b', @@ -32,15 +72,6 @@ describe("Ray", () => { // // expect(vertex.compose.) // }); - test(".vertex.#.continues_with(.vertex.#)", () => { - /** [--|--] */ const B = - Ray.vertex().o({ js: 'A' }).as_reference() - .continues_with(Ray.vertex().o({ js: 'B'}).as_reference()); - - expect(B.type).toBe(RayType.VERTEX); - expect(B.self.self.self.any.js).toBe('B'); - // expect(B.self.self.self.initial.initial.any.js).toBe('A'); - }); test(".vertex.#", () => { /** [--|--] */ const vertex = Ray.vertex().as_reference(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 7f7a20e..1f888ce 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -3,7 +3,7 @@ import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; -// TODO: SHOULDNT CLASSIFY THESE? +// TODO: SHOULDNT CLASSIFY THESE? (And incorporate in Ray??) export enum RayType { // NONE = ' ', REFERENCE = ' | ', @@ -18,9 +18,20 @@ export type Constructor = new (...args: any[]) => T; export type ParameterlessConstructor = new () => T; // TODO: Merge with Arbitrary. -export type Method = (b?: T, ...other: T[]) => T; +export type Recursive = (T | Recursive)[]; +export type Method = (...other: Recursive) => T; export type ArbitraryMethod = (ref: T) => Method; +export type SwitchCases< + T = Ray, + SwitchCase extends string | symbol | number = RayType, + TResult = string | Arbitrary +> = { + [TCase in SwitchCase]?: TResult +} + +export type Implementation = (ref: T) => T; + // export function initial() { // // return function (target: any, propertyKey: string): any { @@ -179,12 +190,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_arbitrary = (): Arbitrary => () => this; // TODO: Should also be abstracted into the Ray - switch = (cases: { - [RayType.REFERENCE]?: string | Arbitrary, - [RayType.INITIAL]?: string | Arbitrary, - [RayType.VERTEX]?: string | Arbitrary, // TODO: Automatic opposite for initial/terminaL?? - [RayType.TERMINAL]?: string | Arbitrary, - }): Ray => { + // TODO: Automatic opposite for initial/terminaL?? + switch = (cases: SwitchCases): Ray => { const _case = cases[this.type]; if (_case === undefined || _.isString(_case)) @@ -193,57 +200,93 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return _case(); } - continues_with2 = Ray.___func( - - )(this); - /** * Constructs a function accepting arbitrary structure based on one implementation of it. * * TODO: Is there some equivalent of this in computer science??? category theory?? * - * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = ... + * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = [[a1, [[[a2]]], [[[[]]], []]], b, [[[]], [], [c]]].compose = ... */ static ___func = ( - a: any + func: Implementation ): ArbitraryMethod => { - return (ref: Ray): Method => (b?: Ray, ...other: Ray[]): Ray => { + /** + * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] + */ + return (ref: Ray): Method => (...any: Recursive): Ray => { + // TODO: This can be much better... + const first = (recursive?: Recursive): Ray | undefined => { + if (recursive === undefined) return; + // if (_.isObject(recursive)) return recursive as unknown as Ray; + + for (let r of recursive) { + if (r === undefined) continue; + if (_.isObject(r)) return r as unknown as Ray; + + // if (r instanceof Ray) + // throw new PreventsImplementationBug(); + + // @ts-ignore + const _first = first(r); + if (_first) + return _first; + } + } + + const _first = first(any); + + if (_first === undefined) + return func(ref); + + // TODO: ANY CASE + // if (any.length === 1) { + return func(new Ray({ + initial: ref.as_arbitrary(), + terminal: _first.as_arbitrary() // TODO Can be lazy./.., generalize this to some way > + }).as_reference()); // TODO; ref here necessary? Probably... + // } + // + // throw new NotImplementedError(); } } // TODO AS += through property - continues_with = (b: Ray): Ray => { + static continues_with = Ray.___func(ref => { // TODO: contiues_with is just composing vertices.. // TODO: Should be: ([this, self_reference, b] as Ray).compose/../merge, dropping this middle vertex, connecting initial/terminal // TODO: Or otherwise: take everything at the vertex, compose it together??>? - return this.switch({ + const { initial, terminal } = ref.self; + + // TODO; Maybe replace switch with 'zip'?, What are the practical differences? + return initial.switch({ [RayType.REFERENCE]: - "We could either go inside the reference and continue there, or expand the direction of reference." + - "We could move when a reference is on the vertex, set the type to vertex from the perspective of the reference", + "We could either go inside the reference and continue there, or expand the direction of reference." + + "We could move when a reference is on the vertex, set the type to vertex from the perspective of the reference", [RayType.TERMINAL]: "", [RayType.INITIAL]: "Could be each element found in this direction, or continue *after* the entire direction", [RayType.VERTEX]: (): Ray => { // const next_vertex = b; // TODO: Could be a reference too, now just force as a next element - if (this.is_none()) { + if (initial.is_none()) { // 'Empty' vertex from this perspective. - this.vertex = b.as_arbitrary(); + initial.vertex = terminal.as_arbitrary(); console.log('first element'); - return b; // TODO: Generally, return something which knows where all continuations are. + return terminal; // TODO: Generally, return something which knows where all continuations are. } - return b.switch({ + return terminal.switch({ [RayType.VERTEX]: () => { - this.self.terminal.equivalent(b.self.initial); - return b; + initial.self.terminal.equivalent(terminal.self.initial); + return terminal; } }); } }); - } + }); + continues_with = Ray.continues_with(this); // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... From e2f447ee1176e44721383365d959f2ae9cdbcd2c Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 13:48:45 +0100 Subject: [PATCH 061/138] 2024/01/13 - Test for calling on a vertex --- src/@orbitmines/explorer/Ray.spec.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 49d0bbd..d8020d7 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -38,6 +38,27 @@ describe("Ray", () => { .any.js ).toBe('B'); }); + test("[.vertex.#, .vertex.#].#.continues_with", () => { + let A = Ray.vertex().o({ js: 'A' }).as_reference(); + let B = Ray.vertex().o({ js: 'B'}).as_reference(); + + B = new Ray({ + initial: A.as_arbitrary(), + terminal: B.as_arbitrary() + }).as_reference().continues_with(); + + expect(B.type).toBe(RayType.VERTEX); + expect(B.self.any.js).toBe('B'); + expect(B.self + .initial.self.initial + .any.js + ).toBe('A'); + expect(B.self + .initial.self.initial + .terminal.self.terminal + .any.js + ).toBe('B'); + }); // test(".vertex.#.debug", () => { // const a = Ray.vertex().as_reference(); // const b = Ray.vertex().as_reference(); From d3cf4748d2b33a8eaf44804e542a8b02adc1bb68 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 14:46:28 +0100 Subject: [PATCH 062/138] 2024/01/13 - Naive equivalence between vertices --- src/@orbitmines/explorer/Ray.spec.ts | 31 +++++++++++++- src/@orbitmines/explorer/Ray.ts | 61 ++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index d8020d7..85ad1b0 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -20,6 +20,35 @@ describe("Ray", () => { expect(method(a)(b).terminal.self.any.js).toBe('B'); expect(method(a)(b).type).toBe(RayType.VERTEX); }); + test(".vertex.#.equivalent(.vertex.#)", () => { + let A = Ray.vertex().o({js: 'A'}) + .as_reference().o({js: 'A.#'}); + let B = Ray.vertex().o({js: 'B'}) + .as_reference().o({js: 'B.#'}); + + expect(A.any.js).toBe('A.#'); + expect(B.any.js).toBe('B.#'); + + let ref = A.equivalent(B); + + expect(ref.self.initial).toBe(A); + expect(ref.self.terminal).toBe(B); + expect(ref.self.initial.any.js).toBe('A.#'); + expect(ref.self.terminal.any.js).toBe('B.#'); + + expect(A.self.any.js).toBe('A'); + expect(B.self.any.js).toBe('B'); + + expect(A.self.self).toBe(B.self); + expect(B.self.self).toBe(A.self); + expect(A.self.self.any.js).toBe('B'); + expect(B.self.self.any.js).toBe('A'); + + expect(B.self.self.self).toBe(B.self); + expect(B.self.self.self.self).toBe(A.self); + expect(B.self.self.self.any.js).toBe('B'); + expect(B.self.self.self.self.any.js).toBe('A'); + }); test(".vertex.#.continues_with(.vertex.#)", () => { let A = Ray.vertex().o({ js: 'A' }).as_reference(); let B = Ray.vertex().o({ js: 'B'}).as_reference(); @@ -40,7 +69,7 @@ describe("Ray", () => { }); test("[.vertex.#, .vertex.#].#.continues_with", () => { let A = Ray.vertex().o({ js: 'A' }).as_reference(); - let B = Ray.vertex().o({ js: 'B'}).as_reference(); + let B = Ray.vertex().o({ js: 'B' }).as_reference(); B = new Ray({ initial: A.as_arbitrary(), diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 1f888ce..4c5a42d 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -195,7 +195,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? const _case = cases[this.type]; if (_case === undefined || _.isString(_case)) - throw new PreventsImplementationBug(_case ?? '??'); + throw new PreventsImplementationBug(_case ?? `?? ${this.type}`); return _case(); } @@ -251,6 +251,50 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } } + static equivalent= Ray.___func(ref => { + const { initial, terminal } = ref.self; + + return initial.switch({ + [RayType.REFERENCE]: () => terminal.switch({ + [RayType.REFERENCE]: () => { + // TODO: IS THIS EVEN HOW THIS SHOULD WORK?? + initial.self = terminal.as_arbitrary(); + terminal.self = initial.as_arbitrary(); + + return ref; + } + }), + [RayType.VERTEX]: () => terminal.switch({ + [RayType.VERTEX]: () => { + // TODO: COULD ADD?? - probably the case for all these equivalences. + initial.self.self = terminal.self.as_arbitrary(); + terminal.self.self = initial.self.as_arbitrary(); + + return ref; + } + }) + }); + + // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? + // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? + }); + equivalent = Ray.equivalent(this); + // protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother + // switch (this.type) { + // case RayType.REFERENCE: + // break; + // case RayType.INITIAL: + // break; + // case RayType.TERMINAL: + // break; + // case RayType.VERTEX: + // break; + // } + // + // this.self = b.as_arbitrary(); + // b.self = this.as_arbitrary(); + // } + // TODO AS += through property static continues_with = Ray.___func(ref => { // TODO: contiues_with is just composing vertices.. @@ -407,21 +451,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? get first(): Ray { throw new NotImplementedError(); } get last(): Ray { throw new NotImplementedError(); } - protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother - switch (this.type) { - case RayType.REFERENCE: - break; - case RayType.INITIAL: - break; - case RayType.TERMINAL: - break; - case RayType.VERTEX: - break; - } - - this.self = b.as_arbitrary(); - b.self = this.as_arbitrary(); - } // TODO: I Don't like this name, but it needs to get across that any equivalency, or any equivalency check for that necessarily, is local. And I want more equivalences, I run more of this method. // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. is_vertex_equivalent = (b: Ray) => { From 8d35d7eedf93d524a56fcdbc08fe4a22ad10600a Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 14:47:37 +0100 Subject: [PATCH 063/138] 2024/01/13 - Naive equivalence between vertices --- src/@orbitmines/explorer/Ray.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 4c5a42d..53fa6cc 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -257,7 +257,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return initial.switch({ [RayType.REFERENCE]: () => terminal.switch({ [RayType.REFERENCE]: () => { - // TODO: IS THIS EVEN HOW THIS SHOULD WORK?? + // TODO: IS THIS EVEN HOW THIS SHOULD WORK?? - Now just takes the pointer and assumes that as its own initial.self = terminal.as_arbitrary(); terminal.self = initial.as_arbitrary(); From abcbd03da4f0bcdcc16cd9083871032e714dfa13 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 20:22:29 +0100 Subject: [PATCH 064/138] 2024/01/13 - First ugly implementation of continuing the ___func as ___next/iterable. --- src/@orbitmines/explorer/Ray.spec.ts | 18 +++ src/@orbitmines/explorer/Ray.ts | 172 ++++++++++++++++----------- 2 files changed, 118 insertions(+), 72 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 85ad1b0..3cba9ed 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -20,6 +20,24 @@ describe("Ray", () => { expect(method(a)(b).terminal.self.any.js).toBe('B'); expect(method(a)(b).type).toBe(RayType.VERTEX); }); + test(".next", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B'}).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C'}).as_reference().o({ js: 'C.#' }); + + let current = A; + + expect(() => current.next).toThrow(); // TODO: Should be empty.. + + A.continues_with(B).continues_with(C); + + expect(current.next.type).toBe(RayType.VERTEX); + // expect(current.next.any.js).toBe('B.#'); TODO, maybe the ref?? + expect(current.next.self.any.js).toBe('B'); + + expect(current.next.next.type).toBe(RayType.VERTEX); + expect(current.next.next.self.any.js).toBe('C'); + }); test(".vertex.#.equivalent(.vertex.#)", () => { let A = Ray.vertex().o({js: 'A'}) .as_reference().o({js: 'A.#'}); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 53fa6cc..c2f168a 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -25,27 +25,13 @@ export type ArbitraryMethod = (ref: T) => Method; export type SwitchCases< T = Ray, SwitchCase extends string | symbol | number = RayType, - TResult = string | Arbitrary + TResult = string | ((self: T) => T) > = { [TCase in SwitchCase]?: TResult } export type Implementation = (ref: T) => T; -// export function initial() { -// -// return function (target: any, propertyKey: string): any { -// Object.defineProperty(target, propertyKey, { -// get: (): any => { return target.initial; }, -// set: (value) => { -// target.initial = value; -// }, -// // enumerable: true, -// // configurable: true -// }); -// } -// } - /** * https://en.wikipedia.org/wiki/Homoiconicity */ @@ -197,7 +183,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (_case === undefined || _.isString(_case)) throw new PreventsImplementationBug(_case ?? `?? ${this.type}`); - return _case(); + return _case(this); } /** @@ -280,20 +266,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }); equivalent = Ray.equivalent(this); // protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother - // switch (this.type) { - // case RayType.REFERENCE: - // break; - // case RayType.INITIAL: - // break; - // case RayType.TERMINAL: - // break; - // case RayType.VERTEX: - // break; - // } - // - // this.self = b.as_arbitrary(); - // b.self = this.as_arbitrary(); - // } // TODO AS += through property static continues_with = Ray.___func(ref => { @@ -332,6 +304,44 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }); continues_with = Ray.continues_with(this); + // @alias('merge') ?? TODO + static compose = Ray.___func(ref => { + const { initial, terminal } = ref.self; + + return initial.switch({ + [RayType.VERTEX]: () => { + const vertex = initial.self; + + // TODO; Implement as restrictive case for Chyp + { + // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) + // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); + + // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. + // if (this.self.initial.is_equivalent(this.self.terminal)) + // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output + } + + /** + * A simple case of what we want to solve here. + * + * Initial Terminal + * ... ... + * [--| ] [ |--] + * [--| ] [ |--] + * [--| ] [ |--] + * [ |--] [--|--] [--| ] + * vertex + * + * And recursively (arbitrarily) match initial/terminal structures. + */ + + throw new NotImplementedError(); + } + }) + }); + compose = Ray.compose(this); + // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... // [[a,d,g],[b,e,h],[c,f,i]] @@ -375,47 +385,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ throw new NotImplementedError(); } - // @alias('merge') ?? - get compose(): Ray { - switch (this.type) { - case RayType.REFERENCE: - case RayType.INITIAL: - case RayType.TERMINAL: { - throw new NotImplementedError(); - } - case RayType.VERTEX: { - const vertex = this.self; - - // TODO; Implement as restrictive case for Chyp - { - // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) - // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); - - // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. - // if (this.self.initial.is_equivalent(this.self.terminal)) - // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output - } - - /** - * A simple case of what we want to solve here. - * - * Initial Terminal - * ... ... - * [--| ] [ |--] - * [--| ] [ |--] - * [--| ] [ |--] - * [ |--] [--|--] [--| ] - * vertex - * - * And recursively (arbitrarily) match initial/terminal structures. - */ - - throw new NotImplementedError(); - } - } - throw new NotImplementedError(); - } - pop = (): Ray => this.switch({ [RayType.VERTEX]: () => { @@ -443,7 +412,66 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ // TODO: These necessarily rever to something which allows you to ask the question of 'next' again. It could return many values (initial/terminal?), a single one: vertex; on which again more structure like a list or something could be defined... get previous(): Ray { throw new NotImplementedError(); } - get next(): Ray { throw new NotImplementedError(); } // TODO: Could need equivalence/skip logic, "already was here", or say, necessarily, it should get visited again, ... again this thing is hard to say generally. + + /** + * + * @param direction Generalized as 'some function'. + */ + static ___next = (direction: (ray: Ray) => Ray) => { + const method = Ray.___func(ref => { + const { initial, terminal } = ref.self; + + return initial.switch({ + [RayType.VERTEX]: () => terminal.switch({ + + // Many possible continuations + [RayType.VERTEX]: () => { + throw new NotImplementedError() + }, + + // No continuations, either a self-reference, or different ways of halting. + [RayType.TERMINAL]: () => Ray.None(), + + // A possible continuation + [RayType.INITIAL]: (ref) => + direction(ref).as_reference() // TODO Why is this reference needed? + .switch({ // TODO: This is applying the function again, should be separate? + // Found a next Vertex. + [RayType.VERTEX]: (self) => self, + // [RayType.VERTEX]: (self) => { throw new NotImplementedError(); }, + + // TODO: Same, but defined a step further + // [RayType.TERMINAL]: () => Ray.None(), + [RayType.TERMINAL]: () => { throw new NotImplementedError(); }, + + // TODO: This switch could repeat infinitely, we need a way to hook into each step.. + [RayType.INITIAL]: () => { throw new NotImplementedError(); }, + + // TODO: Similar to Initial, probably follow the reference, possibly infintely... + [RayType.REFERENCE]: (ref) => { + // throw new NotImplementedError(`${ref.type}/${ref.self.type} - ${ref.any.js}/${ref.self.any.js}`); + // + // if (ref.self.type === RayType.VERTEX) + // return ref.self; + + throw new NotImplementedError(`${ref.type} ${ref.self.type}`); + } + }), + + // TODO: Possibly follow infintely + [RayType.REFERENCE]: () => { throw new NotImplementedError(); } + + }) + }) + }); + + // TODO Implemented as ___func, indicating terminal as the direction of next? as in 'this.next(this => this.self.terminal)' as default, basically, .next is generalizable to any function... + + return (ref: Ray) => method(ref)(direction(ref)); // TODO: Merge __next into __func, make this cleaner... + } + + get next() { return Ray.___next(ref => ref.self.terminal)(this) } + // TODO: Could need equivalence/skip logic, "already was here", or say, necessarily, it should get visited again, ... again this thing is hard to say generally. // TODO: This is the same with rewrite/compile/compose/dpo ... // TODO NEEDS TO CHECK IF THERE'S SOME INITIAL DEFIEND ; for defining if it has halted From 15ac0093de85788b58d923856703c317dde03420 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 21:06:08 +0100 Subject: [PATCH 065/138] 2024/01/13 - First ugly implementation of previous/next of arbitrary functions --- src/@orbitmines/explorer/Ray.spec.ts | 32 ++++++++- src/@orbitmines/explorer/Ray.ts | 102 +++++++++++++++++---------- 2 files changed, 95 insertions(+), 39 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 3cba9ed..d0be074 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -20,24 +20,50 @@ describe("Ray", () => { expect(method(a)(b).terminal.self.any.js).toBe('B'); expect(method(a)(b).type).toBe(RayType.VERTEX); }); - test(".next", () => { + test("[A, B, C][.next, .previous]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B'}).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C'}).as_reference().o({ js: 'C.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); let current = A; expect(() => current.next).toThrow(); // TODO: Should be empty.. + expect(() => current.previous).toThrow(); // TODO: Should be empty.. A.continues_with(B).continues_with(C); + expect(() => current.previous).toThrow(); // TODO: Should be ??.. + expect(() => current.next.next.next).toThrow(); // TODO: Should be ??.. + expect(current.next.type).toBe(RayType.VERTEX); // expect(current.next.any.js).toBe('B.#'); TODO, maybe the ref?? expect(current.next.self.any.js).toBe('B'); expect(current.next.next.type).toBe(RayType.VERTEX); expect(current.next.next.self.any.js).toBe('C'); + + expect(current.next.previous.self.any.js).toBe('A'); + expect(current.next.next.previous.self.any.js).toBe('B'); + expect(current.next.next.previous.previous.self.any.js).toBe('A'); }); + // test(".next(ref => .continues_with(.vertex.#))", () => { + // let A = Ray.vertex().o({ js: 'A' }).as_reference(); + // let B = Ray.vertex().o({ js: 'B'}).as_reference(); + // + // B = A.next(ref => ref.continues_with(B)) + // + // expect(B.type).toBe(RayType.VERTEX); + // expect(B.self.any.js).toBe('B'); + // expect(B.self + // .initial.self.initial + // .any.js + // ).toBe('A'); + // expect(B.self + // .initial.self.initial + // .terminal.self.terminal + // .any.js + // ).toBe('B'); + // }); test(".vertex.#.equivalent(.vertex.#)", () => { let A = Ray.vertex().o({js: 'A'}) .as_reference().o({js: 'A.#'}); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index c2f168a..39d7b3a 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -411,7 +411,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * previous = (): Option => JS.Iterable(this.traverse({ steps: 1, direction: { reverse: true } })).as_ray(); */ // TODO: These necessarily rever to something which allows you to ask the question of 'next' again. It could return many values (initial/terminal?), a single one: vertex; on which again more structure like a list or something could be defined... - get previous(): Ray { throw new NotImplementedError(); } + get previous(): Ray { return Ray.___next(ref => ref.self.initial.as_reference())(this); } + // TODO: Could remove this as_reference... :thinking: /** * @@ -421,45 +422,74 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? const method = Ray.___func(ref => { const { initial, terminal } = ref.self; + // const direction = terminal.type; + + // throw new NotImplementedError(`'${direction}'`); + return initial.switch({ [RayType.VERTEX]: () => terminal.switch({ - // Many possible continuations - [RayType.VERTEX]: () => { - throw new NotImplementedError() - }, - - // No continuations, either a self-reference, or different ways of halting. - [RayType.TERMINAL]: () => Ray.None(), - - // A possible continuation - [RayType.INITIAL]: (ref) => - direction(ref).as_reference() // TODO Why is this reference needed? - .switch({ // TODO: This is applying the function again, should be separate? - // Found a next Vertex. - [RayType.VERTEX]: (self) => self, - // [RayType.VERTEX]: (self) => { throw new NotImplementedError(); }, - - // TODO: Same, but defined a step further - // [RayType.TERMINAL]: () => Ray.None(), - [RayType.TERMINAL]: () => { throw new NotImplementedError(); }, - - // TODO: This switch could repeat infinitely, we need a way to hook into each step.. - [RayType.INITIAL]: () => { throw new NotImplementedError(); }, - - // TODO: Similar to Initial, probably follow the reference, possibly infintely... - [RayType.REFERENCE]: (ref) => { - // throw new NotImplementedError(`${ref.type}/${ref.self.type} - ${ref.any.js}/${ref.self.any.js}`); - // - // if (ref.self.type === RayType.VERTEX) - // return ref.self; - - throw new NotImplementedError(`${ref.type} ${ref.self.type}`); - } + /** + * If we're going in the initial direction (from the perspective of the initial = VERTEX) + * [ |--][--|--] <-- terminal + */ + [RayType.INITIAL]: (ref) => ref.self.switch({ + // TODO REVERSE OF TERMINAL.. + + [RayType.TERMINAL]: (ref) => direction(ref).switch({ // TODO: This is applying the function again, should be separate? + // Found a next Vertex. + [RayType.VERTEX]: (self) => self, + }), }), - // TODO: Possibly follow infintely - [RayType.REFERENCE]: () => { throw new NotImplementedError(); } + /** + * If we're going in the terminal direction (from the perspective of the initial = VERTEX) + * [--|--][--| ] <-- terminal + */ + [RayType.TERMINAL]: (ref) => ref.self.switch({ + + /** + * Many possible continuations (Vertical line is `ref.self`: Asking: 'What are the continuations at the terminal?`) + * + * ? + * [--|--][--| ]<-- ref superposed with ref.self + * ? + */ + [RayType.VERTEX]: () => { + throw new NotImplementedError() + }, + + // No continuations, either a self-reference, or different ways of halting. + [RayType.TERMINAL]: () => { throw new NotImplementedError() }, + + // A possible continuation + [RayType.INITIAL]: (ref) => + direction(ref).switch({ // TODO: This is applying the function again, should be separate? + // Found a next Vertex. + [RayType.VERTEX]: (self) => self, + // [RayType.VERTEX]: (self) => { throw new NotImplementedError(); }, + + // TODO: Same, but defined a step further + // [RayType.TERMINAL]: () => Ray.None(), + [RayType.TERMINAL]: () => { throw new NotImplementedError(); }, + + // TODO: This switch could repeat infinitely, we need a way to hook into each step.. + [RayType.INITIAL]: () => { throw new NotImplementedError(); }, + + // TODO: Similar to Initial, probably follow the reference, possibly infintely... + [RayType.REFERENCE]: (ref) => { + // throw new NotImplementedError(`${ref.type}/${ref.self.type} - ${ref.any.js}/${ref.self.any.js}`); + // + // if (ref.self.type === RayType.VERTEX) + // return ref.self; + + throw new NotImplementedError(`${ref.type} ${ref.self.type}`); + } + }), + + // TODO: Possibly follow infintely + [RayType.REFERENCE]: () => { throw new NotImplementedError(); } + }), }) }) @@ -470,7 +500,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return (ref: Ray) => method(ref)(direction(ref)); // TODO: Merge __next into __func, make this cleaner... } - get next() { return Ray.___next(ref => ref.self.terminal)(this) } + get next() { return Ray.___next(ref => ref.self.terminal.as_reference())(this); } // TODO: Could need equivalence/skip logic, "already was here", or say, necessarily, it should get visited again, ... again this thing is hard to say generally. // TODO: This is the same with rewrite/compile/compose/dpo ... From e44a0b4d8369ed95513fa35887c278b2fa7456eb Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 21:07:05 +0100 Subject: [PATCH 066/138] 2024/01/13 - First ugly implementation of previous/next of arbitrary functions --- src/@orbitmines/explorer/Ray.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index d0be074..8ca0573 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -45,6 +45,8 @@ describe("Ray", () => { expect(current.next.previous.self.any.js).toBe('A'); expect(current.next.next.previous.self.any.js).toBe('B'); expect(current.next.next.previous.previous.self.any.js).toBe('A'); + expect(current.next.previous.next.next.previous.self.any.js).toBe('B'); + expect(current.next.previous.next.next.previous.next.self.any.js).toBe('C'); }); // test(".next(ref => .continues_with(.vertex.#))", () => { // let A = Ray.vertex().o({ js: 'A' }).as_reference(); From f49d87e6b1afa5e96ab10e5eaa85658d088bcda0 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 21:16:12 +0100 Subject: [PATCH 067/138] 2024/01/13 - First ugly implementation of previous/next of arbitrary functions --- src/@orbitmines/explorer/Ray.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 39d7b3a..d98ac93 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -436,7 +436,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? [RayType.INITIAL]: (ref) => ref.self.switch({ // TODO REVERSE OF TERMINAL.. - [RayType.TERMINAL]: (ref) => direction(ref).switch({ // TODO: This is applying the function again, should be separate? + // TODO: direction(ref) is probably concidently the same here.. + [RayType.TERMINAL]: (ref) => direction(ref).switch({ // TODO: This is applying the function again, should be separate? // Found a next Vertex. [RayType.VERTEX]: (self) => self, }), From 09741c6e2e1541f22b7202ab48d1caf2bb05293f Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sat, 13 Jan 2024 21:51:13 +0100 Subject: [PATCH 068/138] 2024/01/13 - Tests for JavaScript generators/iterators --- src/@orbitmines/explorer/Ray.spec.ts | 36 ++++++++++++++++++++++++++++ src/@orbitmines/explorer/Ray.ts | 28 ++++++++++++++++++---- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 8ca0573..9064486 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -48,6 +48,42 @@ describe("Ray", () => { expect(current.next.previous.next.next.previous.self.any.js).toBe('B'); expect(current.next.previous.next.next.previous.next.self.any.js).toBe('C'); }); + test("[A, B, C][.as_array, ...]", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + A.continues_with(B).continues_with(C); + + expect(A.as_array().map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); // TODO: This may or may not be expected behavior, you could make a case for saying it should render both sides for .as_array. ??? + expect(C.as_array().map(ref => ref.self.any.js)).toEqual(['C']); + + expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.as_generator()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect(A.as_string()).toBe('A,B,C'); + + { + + const iterator = A.as_iterator(); + + let array: Ray[] = []; + + while (true) { + let current = iterator.next(); + if (current.done) + break; + + array.push(current.value); + } + + expect(array.map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + + } + + // TODO async_generator / async_iterator / for await * + }); // test(".next(ref => .continues_with(.vertex.#))", () => { // let A = Ray.vertex().o({ js: 'A' }).as_reference(); // let B = Ray.vertex().o({ js: 'B'}).as_reference(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index d98ac93..835ab96 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -489,7 +489,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }), // TODO: Possibly follow infintely - [RayType.REFERENCE]: () => { throw new NotImplementedError(); } + [RayType.REFERENCE]: (ref) => { throw new NotImplementedError(ref.self.type); } }), }) @@ -596,7 +596,25 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // ___compute = () - *traverse(): Generator {} + *traverse(direction: ((ref: Ray) => Ray) = ((ref): Ray => ref.next)): Generator { + // TODO: Also to ___func?? + + if (this.type !== RayType.VERTEX) + throw new NotImplementedError(); + + let current: Ray = this; + + while (true) { + yield current; + + try { + current = current.next; + } catch (e) { + console.error('stopped traversal through implementation error...', e) + break; // TODO: HACKY FOR NOW + } + } + } /** * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. @@ -614,10 +632,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // JS.AsyncIterator as_iterator = (): Iterator => this.as_generator(); // JS.Array - as_array = (): any[] => [...this]; + as_array = (): Ray[] => [...this]; // JS.String - toString = (): string => this.as_array().toString(); - as_string = () => this.toString(); + toString = (): string => this.as_string(); + as_string = (): string => this.as_array().map(ref => ref.self.any.js).join(','); // TODO: PROPER as_int = (): number => { throw new NotImplementedError(); } as_number = this.as_int; From b9d4622d82d3319ff6eb455d1bc8d6a1087fceba Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 15 Jan 2024 13:35:00 +0100 Subject: [PATCH 069/138] 2024/01/15 - More hacky equivalences, compose=merge=continues_with --- src/@orbitmines/explorer/Ray.spec.ts | 106 ++++++++-- src/@orbitmines/explorer/Ray.ts | 185 ++++++++---------- .../external/chyp/Chyp_naive_pass.ts | 82 +++++++- 3 files changed, 250 insertions(+), 123 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 9064486..d916d30 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -25,28 +25,104 @@ describe("Ray", () => { const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - let current = A; - - expect(() => current.next).toThrow(); // TODO: Should be empty.. - expect(() => current.previous).toThrow(); // TODO: Should be empty.. + expect(() => A.next).toThrow(); // TODO: Should be empty.. + expect(() => A.previous).toThrow(); // TODO: Should be empty.. A.continues_with(B).continues_with(C); - expect(() => current.previous).toThrow(); // TODO: Should be ??.. - expect(() => current.next.next.next).toThrow(); // TODO: Should be ??.. + expect(() => A.previous).toThrow(); // TODO: Should be ??.. + expect(() => A.next.next.next).toThrow(); // TODO: Should be ??.. - expect(current.next.type).toBe(RayType.VERTEX); + expect(A.next.type).toBe(RayType.VERTEX); // expect(current.next.any.js).toBe('B.#'); TODO, maybe the ref?? - expect(current.next.self.any.js).toBe('B'); + expect(A.next.self.any.js).toBe('B'); + + expect(A.next.next.type).toBe(RayType.VERTEX); + expect(A.next.next.self.any.js).toBe('C'); + + expect(A.next.previous.self.any.js).toBe('A'); + expect(A.next.next.previous.self.any.js).toBe('B'); + expect(A.next.next.previous.previous.self.any.js).toBe('A'); + expect(A.next.previous.next.next.previous.self.any.js).toBe('B'); + expect(A.next.previous.next.next.previous.next.self.any.js).toBe('C'); + }); + test("[A, [X, Y, Z].initial, B, C][.next, .previous]", () => { + /** + * | | + * |-- A --| |-- B --|-- C --| + * | \ | + * |-- X --| + * | \ | + * |-- Y --| + * | \ | + * |-- Z --| + * | \ | (Destroys the '\' connections) TODO: This should be optional/more complexly constructed + */ + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); + const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); + const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); + + X.continues_with(Y).continues_with(Z); + + const ret = A.continues_with(X.self.initial.as_reference()); + + /** + * | + * |-- A --| + * | \ <-- '\' is 'ret' + * |-- X --| + * | \ + * |-- Y --| + * | \ + * |-- Z --| + * | \ + */ + expect(ret.type).toBe(RayType.INITIAL); + expect(ret.self.terminal.as_reference().is_none()).toBe(false); + expect([...ret.self.terminal.as_reference()].map( + return_ref => return_ref.type + )).toEqual([RayType.VERTEX, RayType.VERTEX, RayType.VERTEX]); + expect([...ret.self.terminal.as_reference()].map( + return_ref => return_ref.self.type + )).toEqual([RayType.TERMINAL, RayType.TERMINAL, RayType.TERMINAL]); + expect([...ret.self.terminal.as_reference()].map( + return_ref => { + const return_vertex = return_ref.self; + const terminal = return_vertex.self; + const continued_vertex = terminal.initial; + + return continued_vertex.any.js; + } + )).toEqual(['X', 'Y', 'Z']); + expect([...ret.self.terminal.as_reference()].map( + return_ref => { + const vertex = return_ref.self; + const terminal = vertex.self; + + return terminal.self.as_reference().is_none(); + } + )).toEqual([true, true, true]); // From the perspective of the 'terminal' it's ignorant of 'ret'. + + expect(A.next.type).toBe(RayType.INITIAL); + + /** + * | | + * |-- A --| |-- B --|-- C --| + * | | + * |-- X --| + * | | + * |-- Y --| + * | | + * |-- Z --| + * | | + */ + ret.continues_with(B).continues_with(C); - expect(current.next.next.type).toBe(RayType.VERTEX); - expect(current.next.next.self.any.js).toBe('C'); - expect(current.next.previous.self.any.js).toBe('A'); - expect(current.next.next.previous.self.any.js).toBe('B'); - expect(current.next.next.previous.previous.self.any.js).toBe('A'); - expect(current.next.previous.next.next.previous.self.any.js).toBe('B'); - expect(current.next.previous.next.next.previous.next.self.any.js).toBe('C'); }); test("[A, B, C][.as_array, ...]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 835ab96..ced4926 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -150,15 +150,19 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // new Ray({ initial: this.as_arbitrary(), vertex: () => this.terminal, js: () => 'terminal ref' }); // TODO: These fields as DEBUG /** [ ] */ const vertex = Ray.None(); - /** [-- ] */ vertex.initial = new Ray({ vertex: Ray.None, terminal: vertex.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); + /** [-- ] */ vertex.initial = vertex.___empty_initial(); /** [ ? ] */ vertex.vertex = value; - /** [ --] */ vertex.terminal = new Ray({ vertex: Ray.None, initial: vertex.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() + /** [ --] */ vertex.terminal = vertex.___empty_terminal(); /** [--?--] */ return vertex; } /** [ |-?] */ static initial = () => Ray.vertex().initial; /** [?-| ] */ static terminal = () => Ray.vertex().terminal; + // TODO; Temp placeholders for now + ___empty_initial = () => new Ray({ vertex: Ray.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); + ___empty_terminal = () => new Ray({ vertex: Ray.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); + static size = (of: number, value: any = undefined): Ray => { let current = Ray.vertex().as_reference(); // TODO; This sort of thing should be lazy for (let i = 0; i < of; i++) { @@ -240,26 +244,24 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? static equivalent= Ray.___func(ref => { const { initial, terminal } = ref.self; - return initial.switch({ - [RayType.REFERENCE]: () => terminal.switch({ - [RayType.REFERENCE]: () => { - // TODO: IS THIS EVEN HOW THIS SHOULD WORK?? - Now just takes the pointer and assumes that as its own - initial.self = terminal.as_arbitrary(); - terminal.self = initial.as_arbitrary(); + // TODO: IS THIS EVEN HOW THIS SHOULD WORK?? - Now just takes the pointer and assumes that as its own - return ref; - } - }), - [RayType.VERTEX]: () => terminal.switch({ - [RayType.VERTEX]: () => { - // TODO: COULD ADD?? - probably the case for all these equivalences. - initial.self.self = terminal.self.as_arbitrary(); - terminal.self.self = initial.self.as_arbitrary(); + if (initial.self.is_none()) { + initial.self = terminal.as_arbitrary(); + } else { + // TODO: COULD ADD?? - probably the case for all these equivalences. + initial.self.self = terminal.self.as_arbitrary(); + // throw new NotImplementedError(); + } - return ref; - } - }) - }); + if (terminal.self.is_none()) { + terminal.self = initial.as_arbitrary(); + } else { + terminal.self.self = initial.self.as_arbitrary(); + // throw new NotImplementedError(); + } + + return ref; // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? @@ -268,6 +270,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother // TODO AS += through property + // @alias('merge, 'continues_with', 'compose') static continues_with = Ray.___func(ref => { // TODO: contiues_with is just composing vertices.. // TODO: Should be: ([this, self_reference, b] as Ray).compose/../merge, dropping this middle vertex, connecting initial/terminal @@ -297,95 +300,54 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? [RayType.VERTEX]: () => { initial.self.terminal.equivalent(terminal.self.initial); return terminal; - } - }); - } - }); - }); - continues_with = Ray.continues_with(this); + }, + [RayType.INITIAL]: () => { + // TODO: You could make a case of preserving the structure of this, or even superposing it on the continuations we're defining here, ... might need a better handle on this at some point + // TODO: Could even have a difference of destroying the connecting itself vs not.. - // @alias('merge') ?? TODO - static compose = Ray.___func(ref => { - const { initial, terminal } = ref.self; + // TODO; This is probably incredibly hacky now - return initial.switch({ - [RayType.VERTEX]: () => { - const vertex = initial.self; + const terminals = [...terminal.self.terminal.as_reference()].map(vertex => vertex.switch({ + [RayType.VERTEX]: (ref) => { - // TODO; Implement as restrictive case for Chyp - { - // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) - // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); + // TODO: Currently takes the vertex, drops the initial/terminal sides and reassigns them to this structure + initial.self.terminal.equivalent(ref.self.initial); + ref.self.terminal = ref.self.___empty_terminal(); - // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. - // if (this.self.initial.is_equivalent(this.self.terminal)) - // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output - } + return ref.self.terminal; + } + })); + + let ret: Ray | undefined; + let current: Ray; + terminals.forEach(terminal => { + const next = Ray.vertex(terminal.as_arbitrary()).as_reference(); - /** - * A simple case of what we want to solve here. - * - * Initial Terminal - * ... ... - * [--| ] [ |--] - * [--| ] [ |--] - * [--| ] [ |--] - * [ |--] [--|--] [--| ] - * vertex - * - * And recursively (arbitrarily) match initial/terminal structures. - */ - - throw new NotImplementedError(); + if (ret === undefined) { + ret = current = next; + } else { + current = current.continues_with(next); + } + }); + + if (ret === undefined) + throw new PreventsImplementationBug(); + + // TODO; Now a Ray/list of [--| ] (terminal) connections. + + return ret.self.initial.as_reference(); // Ret the intial ref of this list TODO + } + }); } - }) + }); }); - compose = Ray.compose(this); + continues_with = Ray.continues_with(this); // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... // [[a,d,g],[b,e,h],[c,f,i]] zip = (): Ray => { throw new NotImplementedError(); } - /** - * Compose structures defined at .initial with those at .terminal, dropping the vertex. ; or if done non-ignorantly. Composing them on another level, ignoring to this vertex. TODO: Allow this freedom - */ - get merge(): Ray { - // concat initial.a + initial.b, terminal.a + terminal.b - // then: either destroy a/b, merge structure... etc.. - // Chyp: destroy b - - // this.initial.equivalent(other.initial); - // this.terminal.equivalent(other.terminal); - - /* - - vd = self.vertex_data(v) - # print("merging %s <- %s" % (v, w)) - - # Where vertex `w` occurs as an edge target, replace it with `v` - for e in self.in_edges(w): - ed = self.edge_data(e) - ed.t = [v if x == w else x for x in ed.t] - vd.in_edges.add(e) - - # Where vertex `w` occurs as an edge source, replace it with `v` - for e in self.out_edges(w): - ed = self.edge_data(e) - ed.s = [v if x == w else x for x in ed.s] - vd.out_edges.add(e) - - # Wherever `w` occurs on the graph boundary, replace it with `v` - self.set_inputs([v if x == w else x for x in self.inputs]) - self.set_outputs([v if x == w else x for x in self.outputs]) - - # Remove references to `w` from the graph - self.remove_vertex(w) - - */ - throw new NotImplementedError(); - } - pop = (): Ray => this.switch({ [RayType.VERTEX]: () => { const previous_vertex = this.self.initial.self.initial.as_reference(); @@ -407,14 +369,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }); /** - * next = (): Option => JS.Iterable(this.traverse({ steps: 1 })).as_ray(); - * previous = (): Option => JS.Iterable(this.traverse({ steps: 1, direction: { reverse: true } })).as_ray(); - */ - // TODO: These necessarily rever to something which allows you to ask the question of 'next' again. It could return many values (initial/terminal?), a single one: vertex; on which again more structure like a list or something could be defined... - get previous(): Ray { return Ray.___next(ref => ref.self.initial.as_reference())(this); } - // TODO: Could remove this as_reference... :thinking: - - /** + * TODO: next/continues_with/compose all generalizable?? * * @param direction Generalized as 'some function'. */ @@ -429,6 +384,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return initial.switch({ [RayType.VERTEX]: () => terminal.switch({ + // TODO Could be an ignorant continuation (as in, the terminal does not have the initial vertex on its .initial). Or you could interpret this as saying, oh this should be a vertex, no information about the continuation definition in between? + [RayType.VERTEX]: (ref) => { throw new NotImplementedError(); }, + /** * If we're going in the initial direction (from the perspective of the initial = VERTEX) * [ |--][--|--] <-- terminal @@ -437,7 +395,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO REVERSE OF TERMINAL.. // TODO: direction(ref) is probably concidently the same here.. - [RayType.TERMINAL]: (ref) => direction(ref).switch({ // TODO: This is applying the function again, should be separate? + [RayType.TERMINAL]: (ref) => + // direction(ref) TODO + ref.self.initial.as_reference() + .switch({ // TODO: This is applying the function again, should be separate? // Found a next Vertex. [RayType.VERTEX]: (self) => self, }), @@ -465,7 +426,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // A possible continuation [RayType.INITIAL]: (ref) => - direction(ref).switch({ // TODO: This is applying the function again, should be separate? + // direction(ref) TODO + ref.self.terminal.as_reference() + .switch({ // TODO: This is applying the function again, should be separate? // Found a next Vertex. [RayType.VERTEX]: (self) => self, // [RayType.VERTEX]: (self) => { throw new NotImplementedError(); }, @@ -501,6 +464,14 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return (ref: Ray) => method(ref)(direction(ref)); // TODO: Merge __next into __func, make this cleaner... } + /** + * next = (): Option => JS.Iterable(this.traverse({ steps: 1 })).as_ray(); + * previous = (): Option => JS.Iterable(this.traverse({ steps: 1, direction: { reverse: true } })).as_ray(); + */ + // TODO: These necessarily rever to something which allows you to ask the question of 'next' again. It could return many values (initial/terminal?), a single one: vertex; on which again more structure like a list or something could be defined... + get previous(): Ray { return Ray.___next(ref => ref.self.initial.as_reference())(this); } + // TODO: Could remove this as_reference... :thinking: + get next() { return Ray.___next(ref => ref.self.terminal.as_reference())(this); } // TODO: Could need equivalence/skip logic, "already was here", or say, necessarily, it should get visited again, ... again this thing is hard to say generally. // TODO: This is the same with rewrite/compile/compose/dpo ... @@ -610,7 +581,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? try { current = current.next; } catch (e) { - console.error('stopped traversal through implementation error...', e) + // console.error('stopped traversal through implementation error...', e) break; // TODO: HACKY FOR NOW } } diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts index 387a61a..21ea45c 100644 --- a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts +++ b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts @@ -456,6 +456,86 @@ // // TODO: Add equivalence/reference on the inputs/output extremes. // } // + +// Merge = compose.. +// /** +// * Compose structures defined at .initial with those at .terminal, dropping the vertex. ; or if done non-ignorantly. Composing them on another level, ignoring to this vertex. TODO: Allow this freedom +// */ +// get merge(): Ray { +// // concat initial.a + initial.b, terminal.a + terminal.b +// // then: either destroy a/b, merge structure... etc.. +// // Chyp: destroy b +// +// // this.initial.equivalent(other.initial); +// // this.terminal.equivalent(other.terminal); +// +// /* +// +// vd = self.vertex_data(v) +// # print("merging %s <- %s" % (v, w)) +// +// # Where vertex `w` occurs as an edge target, replace it with `v` +// for e in self.in_edges(w): +// ed = self.edge_data(e) +// ed.t = [v if x == w else x for x in ed.t] +// vd.in_edges.add(e) +// +// # Where vertex `w` occurs as an edge source, replace it with `v` +// for e in self.out_edges(w): +// ed = self.edge_data(e) +// ed.s = [v if x == w else x for x in ed.s] +// vd.out_edges.add(e) +// +// # Wherever `w` occurs on the graph boundary, replace it with `v` +// self.set_inputs([v if x == w else x for x in self.inputs]) +// self.set_outputs([v if x == w else x for x in self.outputs]) +// +// # Remove references to `w` from the graph +// self.remove_vertex(w) +// +// */ +// throw new NotImplementedError(); +// } + + +// @alias('merge') ?? TODO +// static compose = Ray.___func(ref => { +// const { initial, terminal } = ref.self; +// +// return initial.switch({ +// [RayType.VERTEX]: () => { +// const vertex = initial.self; +// +// // TODO; Implement as restrictive case for Chyp +// { +// // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) +// // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); +// +// // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. +// // if (this.self.initial.is_equivalent(this.self.terminal)) +// // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output +// } +// +// /** +// * A simple case of what we want to solve here. +// * +// * Initial Terminal +// * ... ... +// * [--| ] [ |--] +// * [--| ] [ |--] +// * [--| ] [ |--] +// * [ |--] [--|--] [--| ] +// * vertex +// * +// * And recursively (arbitrarily) match initial/terminal structures. +// */ +// +// throw new NotImplementedError(); +// } +// }) +// }); +// compose = Ray.compose(this); + // /** // * Sequentially compose this graph in-place with another. // * @@ -1393,7 +1473,7 @@ // * Returns True if boundary on lhs embeds injectively // */ // is_left_linear = (): Ray => { -// // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading +// // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading - Or should just equivalence a copy?? // return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() // .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. // } From ccef6d47c99fdf737656703933afe7632d4b1817 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 15 Jan 2024 18:33:41 +0100 Subject: [PATCH 070/138] 2024/01/15 - Iterating on some ways to do equivalences over existing orbits --- src/@orbitmines/explorer/Ray.ts | 99 ++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 19 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index ced4926..5bac18b 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -136,9 +136,12 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. */ - is_none = (): boolean => this.is_orbit(this.self, this.self.self); + is_none = (): boolean => Ray.is_orbit(this.self, this.self.self); - protected is_orbit = (a: Ray, b: Ray) => a === b; // is, ..., appears equal. + /** + * Tries for "global coherence" - since we probably can't actually do that, practically this just means self-reference, were no change is assumed... + */ + static is_orbit = (a: Ray, b: Ray) => a === b; // is, ..., appears equal. protected self_reference = () => this; is_some = (): boolean => !this.is_none(); @@ -179,6 +182,17 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // as_option = (): Ray => Option.Some(this); as_arbitrary = (): Arbitrary => () => this; + as_vertex = (): Ray => { + const vertex = Ray.vertex(this.self.as_arbitrary()); + const current = this.self.self; + + this.self.self = vertex.as_arbitrary(); + + // TODO: Disregards anything on this.self.self?? - or not with current?? + + return vertex.as_reference().continues_with(current.as_reference()); + } + // TODO: Should also be abstracted into the Ray // TODO: Automatic opposite for initial/terminaL?? switch = (cases: SwitchCases): Ray => { @@ -242,29 +256,72 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } static equivalent= Ray.___func(ref => { - const { initial, terminal } = ref.self; + let { initial, terminal } = ref.self; // TODO: IS THIS EVEN HOW THIS SHOULD WORK?? - Now just takes the pointer and assumes that as its own - if (initial.self.is_none()) { - initial.self = terminal.as_arbitrary(); - } else { - // TODO: COULD ADD?? - probably the case for all these equivalences. - initial.self.self = terminal.self.as_arbitrary(); - // throw new NotImplementedError(); + + // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? + // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? + + /** + * The type of equivalence so [initial.type, terminal.type], doesn't matter for us to do this equivalence. So we don't need an "initial.switch + terminal.switch" here, but instead we go directly to the things we're referencing: {initial.self} & {terminal.self} (TODO: is this actually the case??) + * + * initial / terminal - Two ('references') to things we're equivalencing + * initial.self / terminal.self - Two things/.../abstract directions/rays we actually want to connect + * initial.self.self / terminal.self.self - The direction which defines what it's connected to (could be ignorant) + */ + + if (initial.self.is_none() || terminal.self.is_none()) { + /** + * Basically when [].self === [].self.self - See "{Ray.is_orbit}". + * + * TODO: "This is basically already the case, they're already equivalent. - Could take this to mean that we want a degree of separation between them??" + */ + throw new PreventsImplementationBug(`Not expecting empty equivalences (for now)`); //TODO ?? What to do with these? } - if (terminal.self.is_none()) { - terminal.self = initial.as_arbitrary(); - } else { + if (initial.type === RayType.REFERENCE || terminal.type === RayType.REFERENCE) + throw new PreventsImplementationBug(`Not expecting references? ${initial.type}/${terminal.type}`); // TODO REMOVE + + if (initial.self.self.is_none() && terminal.self.self.is_none()) { + // throw new NotImplementedError('a'); + /** + * i.e. initial.self.self.self === initial.self.self.self.self && terminal.self.self.self === terminal.self.self.self.self + * Or in other words: There's no connection currently defined on {initial.self} & {terminal.self}. + * + * Since that's the case, they can just reference each-other directly - Making a slightly larger orbit. + */ + initial.self.self = terminal.self.as_arbitrary(); terminal.self.self = initial.self.as_arbitrary(); - // throw new NotImplementedError(); + return ref; } - return ref; + if (initial.self.self.is_none() || terminal.self.self.is_none()) { + throw new PreventsImplementationBug('What is the case in which one side is ignorant and the other is not?'); + } - // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? - // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? + /** + * If there currently exist structure on (initial/terminal).self.self (i.e. existing connections), we need to add to them. + */ + + // TODO: COULD ADD?? - probably the case for all these equivalences. + // TODO: Should do, one timesteap ahead, collapse one reference, and then recursively call continues_with on the vlaue at the reference, until it yields something. + + + if (!(Ray.is_orbit(initial.self, initial.self.self.self) && Ray.is_orbit(terminal.self, terminal.self.self.self))) { + throw new PreventsImplementationBug('Just add?'); + } + + + // throw new PreventsImplementationBug(`[${initial.self.initial.any.js}]-[${initial.self.initial.as_reference().next.self.any.js}]/[${terminal.self.terminal.any.js}]`) + + // TODO NEEDS THIS??) + // 'Unwrap the references to a line' + + initial.self.as_vertex().continues_with(terminal.self.as_vertex()) + + return ref; }); equivalent = Ray.equivalent(this); // protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother @@ -284,7 +341,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? "We could either go inside the reference and continue there, or expand the direction of reference." + "We could move when a reference is on the vertex, set the type to vertex from the perspective of the reference", [RayType.TERMINAL]: "", - [RayType.INITIAL]: "Could be each element found in this direction, or continue *after* the entire direction", + // [RayType.INITIAL]: () => { + // + // }, + + // "Could be each element found in this direction, or continue *after* the entire direction", ; TODO: This continue is probably more appropraite for vertex, then move to the last one, and compose there... [RayType.VERTEX]: (): Ray => { // const next_vertex = b; // TODO: Could be a reference too, now just force as a next element @@ -298,7 +359,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return terminal.switch({ [RayType.VERTEX]: () => { - initial.self.terminal.equivalent(terminal.self.initial); + initial.self.terminal.as_reference().equivalent(terminal.self.initial.as_reference()); return terminal; }, [RayType.INITIAL]: () => { @@ -311,7 +372,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? [RayType.VERTEX]: (ref) => { // TODO: Currently takes the vertex, drops the initial/terminal sides and reassigns them to this structure - initial.self.terminal.equivalent(ref.self.initial); + initial.self.terminal.as_reference().equivalent(ref.self.initial.as_reference()); ref.self.terminal = ref.self.___empty_terminal(); return ref.self.terminal; From bf07fe0c24f9c9bd653c89913f8390c8034c56ac Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 15 Jan 2024 21:41:38 +0100 Subject: [PATCH 071/138] 2024/01/15 - Refactoring - moving some stuff around --- src/@orbitmines/explorer/Ray.spec.ts | 174 ++++++----- src/@orbitmines/explorer/Ray.ts | 269 +++++++++++------- .../external/chyp/Chyp_naive_pass.ts | 2 +- 3 files changed, 274 insertions(+), 171 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index d916d30..a94b3a8 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -5,7 +5,7 @@ describe("Ray", () => { const method = Ray.___func((ref: Ray): Ray => new Ray({ initial: ref.self.initial.as_arbitrary(), terminal: ref.self.terminal.as_arbitrary() - }).o({ js: ref.type })); + }).o({ js: ref.type })).as_method; expect(method(Ray.vertex().as_reference().as_reference())().any.js).toBe(RayType.REFERENCE); expect(method(Ray.vertex().as_reference())().any.js).toBe(RayType.VERTEX); @@ -46,83 +46,115 @@ describe("Ray", () => { expect(A.next.previous.next.next.previous.self.any.js).toBe('B'); expect(A.next.previous.next.next.previous.next.self.any.js).toBe('C'); }); - test("[A, [X, Y, Z].initial, B, C][.next, .previous]", () => { - /** - * | | - * |-- A --| |-- B --|-- C --| - * | \ | - * |-- X --| - * | \ | - * |-- Y --| - * | \ | - * |-- Z --| - * | \ | (Destroys the '\' connections) TODO: This should be optional/more complexly constructed - */ + // test("[A, [X, Y, Z].initial, B, C][.next, .previous]", () => { + // /** + // * | | + // * |-- A --| |-- B --|-- C --| + // * | \ | + // * |-- X --| + // * | \ | + // * |-- Y --| + // * | \ | + // * |-- Z --| + // * | \ | (Destroys the '\' connections) TODO: This should be optional/more complexly constructed + // */ + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + // + // const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); + // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); + // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); + // + // X.continues_with(Y).continues_with(Z); + // + // const ret = A.continues_with(X.self.initial.as_reference()); + // + // /** + // * | + // * |-- A --| + // * | \ <-- '\' is 'ret' + // * |-- X --| + // * | \ + // * |-- Y --| + // * | \ + // * |-- Z --| + // * | \ + // */ + // expect(ret.type).toBe(RayType.INITIAL); + // expect(ret.self.terminal.as_reference().is_none()).toBe(false); + // expect([...ret.self.terminal.as_reference()].map( + // return_ref => return_ref.type + // )).toEqual([RayType.VERTEX, RayType.VERTEX, RayType.VERTEX]); + // expect([...ret.self.terminal.as_reference()].map( + // return_ref => return_ref.self.type + // )).toEqual([RayType.TERMINAL, RayType.TERMINAL, RayType.TERMINAL]); + // expect([...ret.self.terminal.as_reference()].map( + // return_ref => { + // const return_vertex = return_ref.self; + // const terminal = return_vertex.self; + // const continued_vertex = terminal.initial; + // + // return continued_vertex.any.js; + // } + // )).toEqual(['X', 'Y', 'Z']); + // expect([...ret.self.terminal.as_reference()].map( + // return_ref => { + // const vertex = return_ref.self; + // const terminal = vertex.self; + // + // return terminal.self.as_reference().is_none(); + // } + // )).toEqual([true, true, true]); // From the perspective of the 'terminal' it's ignorant of 'ret'. + // + // expect(A.next.type).toBe(RayType.INITIAL); + // + // /** + // * | | + // * |-- A --| |-- B --|-- C --| + // * | | + // * |-- X --| + // * | | + // * |-- Y --| + // * | | + // * |-- Z --| + // * | | + // */ + // ret.continues_with(B).continues_with(C); + // + // + // }); + // test(".as_vertex", () => { + // const initial = Ray.terminal().o({js: 'A'}).as_reference().o({js: 'A.#'}); + // const terminal= Ray.initial().o({js: 'B'}).as_reference().o({js: 'B.#'}); + // + // initial.self = terminal.as_arbitrary(); + // terminal.self = initial.as_arbitrary(); + // + // const as_vertex = initial.as_vertex(); + // expect(as_vertex.self.any.js).toBe('B'); + // }); + test(".#.equivalent(.#)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); - const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); - const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); - - X.continues_with(Y).continues_with(Z); - const ret = A.continues_with(X.self.initial.as_reference()); - - /** - * | - * |-- A --| - * | \ <-- '\' is 'ret' - * |-- X --| - * | \ - * |-- Y --| - * | \ - * |-- Z --| - * | \ - */ - expect(ret.type).toBe(RayType.INITIAL); - expect(ret.self.terminal.as_reference().is_none()).toBe(false); - expect([...ret.self.terminal.as_reference()].map( - return_ref => return_ref.type - )).toEqual([RayType.VERTEX, RayType.VERTEX, RayType.VERTEX]); - expect([...ret.self.terminal.as_reference()].map( - return_ref => return_ref.self.type - )).toEqual([RayType.TERMINAL, RayType.TERMINAL, RayType.TERMINAL]); - expect([...ret.self.terminal.as_reference()].map( - return_ref => { - const return_vertex = return_ref.self; - const terminal = return_vertex.self; - const continued_vertex = terminal.initial; - - return continued_vertex.any.js; - } - )).toEqual(['X', 'Y', 'Z']); - expect([...ret.self.terminal.as_reference()].map( - return_ref => { - const vertex = return_ref.self; - const terminal = vertex.self; + const ret = A.equivalent(B); - return terminal.self.as_reference().is_none(); - } - )).toEqual([true, true, true]); // From the perspective of the 'terminal' it's ignorant of 'ret'. - - expect(A.next.type).toBe(RayType.INITIAL); + expect(A.self.self.any.js).toBe('B'); + expect(B.self.self.any.js).toBe('A'); - /** - * | | - * |-- A --| |-- B --|-- C --| - * | | - * |-- X --| - * | | - * |-- Y --| - * | | - * |-- Z --| - * | | - */ - ret.continues_with(B).continues_with(C); + expect(A.self.self.self.any.js).toBe('A'); + expect(B.self.self.self.any.js).toBe('B'); + expect(ret.self.initial.any.js).toBe('A.#'); + expect(ret.self.initial.self.any.js).toBe('A'); + expect(ret.self.initial.self.self.any.js).toBe('B'); + expect(ret.self.initial.self.self.self.any.js).toBe('A'); + expect(ret.self.terminal.any.js).toBe('B.#'); + expect(ret.self.terminal.self.any.js).toBe('B'); + expect(ret.self.terminal.self.self.any.js).toBe('A'); + expect(ret.self.terminal.self.self.self.any.js).toBe('B'); }); test("[A, B, C][.as_array, ...]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 5bac18b..d4e4647 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,4 +1,4 @@ -import _ from "lodash"; +import _, {initial} from "lodash"; import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; @@ -6,10 +6,10 @@ import {InterfaceOptions} from "./OrbitMinesExplorer"; // TODO: SHOULDNT CLASSIFY THESE? (And incorporate in Ray??) export enum RayType { // NONE = ' ', - REFERENCE = ' | ', - INITIAL = ' |-?', - TERMINAL = '?-| ', - VERTEX = '--|--', + REFERENCE = 'REFERENCE: | ', + INITIAL = 'INITIAL: |-?', + TERMINAL = 'TERMINAL: ?-| ', + VERTEX = 'VERTEX: --|--', } export type ParameterlessFunction = () => T; @@ -190,70 +190,76 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO: Disregards anything on this.self.self?? - or not with current?? - return vertex.as_reference().continues_with(current.as_reference()); + return vertex.as_reference();//.continues_with(current.as_reference()); } - // TODO: Should also be abstracted into the Ray - // TODO: Automatic opposite for initial/terminaL?? - switch = (cases: SwitchCases): Ray => { - const _case = cases[this.type]; - - if (_case === undefined || _.isString(_case)) - throw new PreventsImplementationBug(_case ?? `?? ${this.type}`); - - return _case(this); - } /** - * Constructs a function accepting arbitrary structure based on one implementation of it. * - * TODO: Is there some equivalent of this in computer science??? category theory?? * - * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = [[a1, [[[a2]]], [[[[]]], []]], b, [[[]], [], [c]]].compose = ... + * TODO: switch/match Should be abstracted into Ray? */ - static ___func = ( - func: Implementation - ): ArbitraryMethod => { + match = (cases: { + [RayType.VERTEX]: (self: Ray) => Ray, + + CONTINUATION: (self: Ray) => Ray, /** - * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] + * Can be used to override default dereference behavior. + * TODO: This should probably be configurable on a more global setting. */ - return (ref: Ray): Method => (...any: Recursive): Ray => { - // TODO: This can be much better... - const first = (recursive?: Recursive): Ray | undefined => { - if (recursive === undefined) return; - // if (_.isObject(recursive)) return recursive as unknown as Ray; - - for (let r of recursive) { - if (r === undefined) continue; - if (_.isObject(r)) return r as unknown as Ray; - - // if (r instanceof Ray) - // throw new PreventsImplementationBug(); - - // @ts-ignore - const _first = first(r); - if (_first) - return _first; - } - } + [RayType.REFERENCE]?: (self: Ray) => Ray + }): Ray => { + const { CONTINUATION } = cases; + const { initial } = this.self; - const _first = first(any); + return initial.___primitive_switch({ - if (_first === undefined) - return func(ref); + [RayType.VERTEX]: cases[RayType.VERTEX], - // TODO: ANY CASE - // if (any.length === 1) { - return func(new Ray({ - initial: ref.as_arbitrary(), - terminal: _first.as_arbitrary() // TODO Can be lazy./.., generalize this to some way > - }).as_reference()); // TODO; ref here necessary? Probably... - // } - // - // throw new NotImplementedError(); - } + [RayType.TERMINAL]: (self + // , disambiguate: { [RayType.INITIAL]: (), } + ) => CONTINUATION(self), + + [RayType.REFERENCE]: () => Ray.vertex(new Ray({ + initial: () => initial.self, // Dereference + terminal: initial._terminal // Pass terminal without evaluating + }).as_arbitrary()), + + }) } + protected ___primitive_switch = (cases: SwitchCases): Ray => { + const _case = cases[this.type]; + + if (_case === undefined || _.isString(_case)) + throw new PreventsImplementationBug(_case ?? `Unhandled switch case; [${this.type}]`); + + return _case(this); + } + + // @alias('merge, 'continues_with', 'compose') + /** + * Compose as "Equivalence at Continuations" + * + * `A.compose(B).compose(C)` = `A.` + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence + */ + static compose = Ray.___func(ref => ref.match({ + [RayType.VERTEX]: () => { throw new NotImplementedError(); }, + CONTINUATION: (self): Ray => { + + } + })); + compose = Ray.compose.as_method(this); + + // static equivalent2 = Ray.___func(ref => { + // let { initial, terminal} = ref.self; + // + // return Ray.vertex(initial).compose(terminal); + // }); + // equivalent2 = Ray.compose(this); + static equivalent= Ray.___func(ref => { let { initial, terminal } = ref.self; @@ -265,7 +271,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? /** - * The type of equivalence so [initial.type, terminal.type], doesn't matter for us to do this equivalence. So we don't need an "initial.switch + terminal.switch" here, but instead we go directly to the things we're referencing: {initial.self} & {terminal.self} (TODO: is this actually the case??) + * The type of equivalence so [initial.type, terminal.type], doesn't matter for us to do this equivalence. So we don't need an "initial.___primitive_switch + terminal.___primitive_switch" here, but instead we go directly to the things we're referencing: {initial.self} & {terminal.self} (TODO: is this actually the case??) * * initial / terminal - Two ('references') to things we're equivalencing * initial.self / terminal.self - Two things/.../abstract directions/rays we actually want to connect @@ -310,33 +316,28 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (!(Ray.is_orbit(initial.self, initial.self.self.self) && Ray.is_orbit(terminal.self, terminal.self.self.self))) { - throw new PreventsImplementationBug('Just add?'); + // throw new PreventsImplementationBug('Just add?'); + initial.self.continues_with(terminal.self); + return ref; } // throw new PreventsImplementationBug(`[${initial.self.initial.any.js}]-[${initial.self.initial.as_reference().next.self.any.js}]/[${terminal.self.terminal.any.js}]`) - // TODO NEEDS THIS??) - // 'Unwrap the references to a line' - + // TODO initial.self.as_vertex().continues_with(terminal.self.as_vertex()) return ref; }); - equivalent = Ray.equivalent(this); + equivalent = Ray.equivalent.as_method(this); // protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother // TODO AS += through property - // @alias('merge, 'continues_with', 'compose') static continues_with = Ray.___func(ref => { - // TODO: contiues_with is just composing vertices.. - // TODO: Should be: ([this, self_reference, b] as Ray).compose/../merge, dropping this middle vertex, connecting initial/terminal - // TODO: Or otherwise: take everything at the vertex, compose it together??>? - const { initial, terminal } = ref.self; // TODO; Maybe replace switch with 'zip'?, What are the practical differences? - return initial.switch({ + return initial.___primitive_switch({ [RayType.REFERENCE]: "We could either go inside the reference and continue there, or expand the direction of reference." + "We could move when a reference is on the vertex, set the type to vertex from the perspective of the reference", @@ -357,7 +358,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return terminal; // TODO: Generally, return something which knows where all continuations are. } - return terminal.switch({ + return terminal.___primitive_switch({ [RayType.VERTEX]: () => { initial.self.terminal.as_reference().equivalent(terminal.self.initial.as_reference()); return terminal; @@ -368,7 +369,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO; This is probably incredibly hacky now - const terminals = [...terminal.self.terminal.as_reference()].map(vertex => vertex.switch({ + const terminals = [...terminal.self.terminal.as_reference()].map(vertex => vertex.___primitive_switch({ [RayType.VERTEX]: (ref) => { // TODO: Currently takes the vertex, drops the initial/terminal sides and reassigns them to this structure @@ -397,19 +398,19 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO; Now a Ray/list of [--| ] (terminal) connections. return ret.self.initial.as_reference(); // Ret the intial ref of this list TODO - } + }, }); } }); }); - continues_with = Ray.continues_with(this); + continues_with = Ray.continues_with.as_method(this); // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... // [[a,d,g],[b,e,h],[c,f,i]] zip = (): Ray => { throw new NotImplementedError(); } - pop = (): Ray => this.switch({ + pop = (): Ray => this.___primitive_switch({ [RayType.VERTEX]: () => { const previous_vertex = this.self.initial.self.initial.as_reference(); @@ -417,7 +418,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return this; // TODO; Already empty, perhaps throw } - return previous_vertex.switch({ + return previous_vertex.___primitive_switch({ [RayType.VERTEX]: () => { console.log(previous_vertex) // TODO: NONHACKY @@ -429,12 +430,72 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } }); + /** + * Constructs a function accepting arbitrary structure based on one implementation of it. + * + * TODO: Is there some equivalent of this in computer science??? category theory?? + * + * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = [[a1, [[[a2]]], [[[[]]], []]], b, [[[]], [], [c]]].compose = ... + */ + static ___func( + step: Implementation, + ): { + as_method: ArbitraryMethod + } { + // const func = new Ray({ + // terminal: (): Ray => { + // + // } + // }); + + return { + + /** + * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] + */ + as_method: (ref: Ray): Method => (...any: Recursive): Ray => { + // TODO: This can be much better... + const first = (recursive?: Recursive): Ray | undefined => { + if (recursive === undefined) return; + // if (_.isObject(recursive)) return recursive as unknown as Ray; + + for (let r of recursive) { + if (r === undefined) continue; + if (_.isObject(r)) return r as unknown as Ray; + + // if (r instanceof Ray) + // throw new PreventsImplementationBug(); + + // @ts-ignore + const _first = first(r); + if (_first) + return _first; + } + } + + const _first = first(any); + + if (_first === undefined) + return step(ref); + + return step(new Ray({ + initial: ref.as_arbitrary(), + terminal: _first.as_arbitrary() + }).as_reference()); + + // TODO: ANY CASE + // if (any.length === 1) { + // } + } + } + } + /** * TODO: next/continues_with/compose all generalizable?? * * @param direction Generalized as 'some function'. */ - static ___next = (direction: (ray: Ray) => Ray) => { + static ___next = (step: Implementation) => { const method = Ray.___func(ref => { const { initial, terminal } = ref.self; @@ -442,8 +503,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // throw new NotImplementedError(`'${direction}'`); - return initial.switch({ - [RayType.VERTEX]: () => terminal.switch({ + return initial.___primitive_switch({ + [RayType.VERTEX]: () => terminal.___primitive_switch({ // TODO Could be an ignorant continuation (as in, the terminal does not have the initial vertex on its .initial). Or you could interpret this as saying, oh this should be a vertex, no information about the continuation definition in between? [RayType.VERTEX]: (ref) => { throw new NotImplementedError(); }, @@ -452,14 +513,14 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * If we're going in the initial direction (from the perspective of the initial = VERTEX) * [ |--][--|--] <-- terminal */ - [RayType.INITIAL]: (ref) => ref.self.switch({ + [RayType.INITIAL]: (ref) => ref.self.___primitive_switch({ // TODO REVERSE OF TERMINAL.. - // TODO: direction(ref) is probably concidently the same here.. + // TODO: Implementation(ref) is probably concidently the same here.. [RayType.TERMINAL]: (ref) => // direction(ref) TODO ref.self.initial.as_reference() - .switch({ // TODO: This is applying the function again, should be separate? + .___primitive_switch({ // TODO: This is applying the function again, should be separate? // Found a next Vertex. [RayType.VERTEX]: (self) => self, }), @@ -469,7 +530,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * If we're going in the terminal direction (from the perspective of the initial = VERTEX) * [--|--][--| ] <-- terminal */ - [RayType.TERMINAL]: (ref) => ref.self.switch({ + [RayType.TERMINAL]: (ref) => ref.self.___primitive_switch({ /** * Many possible continuations (Vertical line is `ref.self`: Asking: 'What are the continuations at the terminal?`) @@ -489,7 +550,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? [RayType.INITIAL]: (ref) => // direction(ref) TODO ref.self.terminal.as_reference() - .switch({ // TODO: This is applying the function again, should be separate? + .___primitive_switch({ // TODO: This is applying the function again, should be separate? // Found a next Vertex. [RayType.VERTEX]: (self) => self, // [RayType.VERTEX]: (self) => { throw new NotImplementedError(); }, @@ -518,30 +579,40 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }) }) - }); + }).as_method; // TODO Implemented as ___func, indicating terminal as the direction of next? as in 'this.next(this => this.self.terminal)' as default, basically, .next is generalizable to any function... - return (ref: Ray) => method(ref)(direction(ref)); // TODO: Merge __next into __func, make this cleaner... + return (ref: Ray) => method(ref)(step(ref)); // TODO: Merge __next into __func, make this cleaner... } /** - * next = (): Option => JS.Iterable(this.traverse({ steps: 1 })).as_ray(); - * previous = (): Option => JS.Iterable(this.traverse({ steps: 1, direction: { reverse: true } })).as_ray(); + * Helper methods for commonly used directions + * + * TODO: Link to step-wise walk as any function - lazy, not traversing certain paths, etc.. (for last/..) */ - // TODO: These necessarily rever to something which allows you to ask the question of 'next' again. It could return many values (initial/terminal?), a single one: vertex; on which again more structure like a list or something could be defined... - get previous(): Ray { return Ray.___next(ref => ref.self.initial.as_reference())(this); } - // TODO: Could remove this as_reference... :thinking: - - get next() { return Ray.___next(ref => ref.self.terminal.as_reference())(this); } - // TODO: Could need equivalence/skip logic, "already was here", or say, necessarily, it should get visited again, ... again this thing is hard to say generally. - // TODO: This is the same with rewrite/compile/compose/dpo ... - - // TODO NEEDS TO CHECK IF THERE'S SOME INITIAL DEFIEND ; for defining if it has halted - - get first(): Ray { throw new NotImplementedError(); } - get last(): Ray { throw new NotImplementedError(); } + static directions = { + next: (ref: Ray) => ref.self.terminal.as_reference(), + previous: (ref: Ray) => ref.self.initial.as_reference(), + } + /** + * .next + */ + get next() { return Ray.___next(Ray.directions.next)(this); } + has_next = (step: Implementation = Ray.directions.next): boolean => step(this).is_none(); + // @alias('end', 'result') + last = (step: Implementation = Ray.directions.next): Ray => { + const next = step(this); + return next.is_none() ? next.last(step) : this; + } + /** + * .previous + */ + get previous(): Ray { return Ray.___next(Ray.directions.previous)(this); } + has_previous = (step: Implementation = Ray.directions.previous): boolean => this.has_next(step); + first = (step: Implementation = Ray.directions.previous): Ray => this.last(step); + // TODO: I Don't like this name, but it needs to get across that any equivalency, or any equivalency check for that necessarily, is local. And I want more equivalences, I run more of this method. // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. is_vertex_equivalent = (b: Ray) => { @@ -628,11 +699,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // ___compute = () - *traverse(direction: ((ref: Ray) => Ray) = ((ref): Ray => ref.next)): Generator { + *traverse(step: ((ref: Ray) => Ray) = ((ref): Ray => ref.next)): Generator { // TODO: Also to ___func?? if (this.type !== RayType.VERTEX) - throw new NotImplementedError(); + throw new NotImplementedError(`[${this.type}]`); let current: Ray = this; diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts index 21ea45c..9797cbb 100644 --- a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts +++ b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts @@ -502,7 +502,7 @@ // static compose = Ray.___func(ref => { // const { initial, terminal } = ref.self; // -// return initial.switch({ +// return initial.___primitive_switch({ // [RayType.VERTEX]: () => { // const vertex = initial.self; // From 648555ef57e91c026a3667e47afef91398c3bb18 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 14:40:59 +0100 Subject: [PATCH 072/138] 2024/01/16 - Iterating on some ideas to implement 'next' --- src/@orbitmines/explorer/Ray.spec.ts | 92 +++++++++++ src/@orbitmines/explorer/Ray.ts | 222 ++++++++++++++++++--------- 2 files changed, 241 insertions(+), 73 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index a94b3a8..eafe295 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -20,6 +20,98 @@ describe("Ray", () => { expect(method(a)(b).terminal.self.any.js).toBe('B'); expect(method(a)(b).type).toBe(RayType.VERTEX); }); + test(".next", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + A.continues_with(B).continues_with(C); + + let pointer = new Ray({ + initial: () => A, + terminal: () => Ray.directions.next(A), + }); + + /** + * ____________ + * [ |--] [--| ][ |--] [--| ][ |--] [--| ] + * [--A--] [--B--] [--C--] + */ + expect(pointer.initial.type).toBe(RayType.VERTEX); + expect(pointer.terminal.type).toBe(RayType.TERMINAL); + + pointer = Ray.next2(pointer); + + /** + * ______________ + * [ |--] [--| ][ |--] [--| ][ |--] [--| ] + * [--A--] [--B--] [--C--] + */ + expect(pointer.initial.type).toBe(RayType.TERMINAL); + expect(pointer.terminal.type).toBe(RayType.INITIAL); + pointer = Ray.next2(pointer); + + /** + * ____________ + * [ |--] [--| ][ |--] [--| ][ |--] [--| ] + * [--A--] [--B--] [--C--] + */ + expect(pointer.initial.type).toBe(RayType.INITIAL); + expect(pointer.terminal.type).toBe(RayType.VERTEX); + expect(pointer.terminal.self.any.js).toBe('B'); + + pointer = Ray.next2(pointer); + + /** + * ____________ + * [ |--] [--| ][ |--] [--| ][ |--] [--| ] + * [--A--] [--B--] [--C--] + */ + expect(pointer.initial.type).toBe(RayType.VERTEX); + expect(pointer.terminal.type).toBe(RayType.TERMINAL); + + pointer = Ray.next2(pointer); + + /** + * ______________ + * [ |--] [--| ][ |--] [--| ][ |--] [--| ] + * [--A--] [--B--] [--C--] + */ + expect(pointer.initial.type).toBe(RayType.TERMINAL); + expect(pointer.terminal.type).toBe(RayType.INITIAL); + + pointer = Ray.next2(pointer); + + /** + * ____________ + * [ |--] [--| ][ |--] [--| ][ |--] [--| ] + * [--A--] [--B--] [--C--] + */ + expect(pointer.initial.type).toBe(RayType.INITIAL); + expect(pointer.terminal.type).toBe(RayType.VERTEX); + expect(pointer.terminal.self.any.js).toBe('C'); + + pointer = Ray.next2(pointer); + + /** + * ____________ + * [ |--] [--| ][ |--] [--| ][ |--] [--| ] + * [--A--] [--B--] [--C--] + */ + expect(pointer.initial.type).toBe(RayType.VERTEX); + expect(pointer.terminal.type).toBe(RayType.TERMINAL); + + pointer = Ray.next2(pointer); + + /** + * _______ + * [ |--] [--| ][ |--] [--| ][ |--] [--| ] + * [--A--] [--B--] [--C--] + */ + expect(pointer.initial.type).toBe(RayType.TERMINAL); + // expect(pointer.terminal.type).toBe(RayType.TERMINAL); ?? + expect(pointer.terminal.is_none()).toBe(true); + }); test("[A, B, C][.next, .previous]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index d4e4647..a8ba92b 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -11,6 +11,8 @@ export enum RayType { TERMINAL = 'TERMINAL: ?-| ', VERTEX = 'VERTEX: --|--', } +export type Boundary = RayType.INITIAL | RayType.TERMINAL; +const opposite = (boundary: Boundary): Boundary => boundary === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL; export type ParameterlessFunction = () => T; export type Arbitrary = (...args: any[]) => T; @@ -69,7 +71,6 @@ export type DebugRay = { * * TODO: Any javascript class, allow warpper of function names around any ray, as a possible match * TODO: All the methods defined here should be implemented in some Ray structure at some point - * TODO: Easy method to create initial/terminal, right now it's a bit obscure * * TODO: Maybe want a way to destroy from one end, so that if other references try to look, they won't find additional structure. - More as a javascript implementation quirck if anything? * @@ -100,8 +101,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? get self(): Ray { return this.vertex; }; set self(self: Arbitrary) { this.vertex = self; } - [index: number]: Ray; - constructor({ initial, vertex, terminal, }: Partial> = {}) { this._initial = initial ?? Ray.None; this._vertex = vertex ?? this.self_reference; // TODO: None, could also self-reference the ray on which it's defining to be None. Now it's just an ignorant loop. @@ -193,38 +192,160 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return vertex.as_reference();//.continues_with(current.as_reference()); } + get dereference() { return this.self.self.as_reference(); } /** * * * TODO: switch/match Should be abstracted into Ray? */ - match = (cases: { - [RayType.VERTEX]: (self: Ray) => Ray, + static next2 = (ref: Ray) => { + const { initial } = ref; - CONTINUATION: (self: Ray) => Ray, + /** + * Should return vertex, for one possible next step + * Initial for many + * Terminal for none + * Reference for ??? + */ + + /** + * Dereferencing is likely in many cases quickly subject to infinite stepping. + * + * REFERENCE -> Dereference (this.self.self) + * INITIAL/INITIAL -> Dereference (this.self.terminal) + * TERMINAL/TERMINAL -> Dereference (this.self.initial) + * VERTEX/VERTEX -> ??? + * + * - Could be that this means that there's no continuation, a self-reference defined here, or it's some mechanism of halting. + * + * - TODO: Simple example of infinitely finding terminals, or a reference to 'nothing - infinitely'. + * - TODO: Could return both dereference sides as possible options + */ + + const next_pointer = (ref: Ray, terminal: Ray, next: Arbitrary) => new Ray({ + initial: terminal.as_arbitrary(), + vertex: ref.as_arbitrary(), + terminal: next, + }); /** - * Can be used to override default dereference behavior. - * TODO: This should probably be configurable on a more global setting. + * INITIAL/TERMINAL -> possible previous - TERMINAL.self.initial (pass to step) + * TERMINAL/INITIAL -> possible next - INITIAL.self.terminal (pass to step) */ + const follow_direction = (terminal: Ray): Ray => next_pointer(ref, terminal, () => terminal.___primitive_switch({ + [RayType.INITIAL]: Ray.directions.next, + [RayType.TERMINAL]: Ray.directions.previous, + })); + + const dereference = (terminal: Ray) => next_pointer(ref, terminal, () => terminal.dereference); + + /** + * TERMINAL -> VERTEX (next: VERTEX -> INITIAL) + * INITIAL -> VERTEX (next: VERTEX -> TERMINAL) + */ + const arbitrary_continuations = (terminal: Ray): Ray => next_pointer(ref, terminal, () => initial.___primitive_switch({ + [RayType.INITIAL]: (initial) => Ray.directions.next(terminal), + [RayType.TERMINAL]: (initial) => Ray.directions.previous(terminal), + })); + + const found_vertex = (ref: Ray): Ray => { + throw new NotImplementedError(); + } + + const boundary = (boundary: Boundary) => (terminal: Ray): Ray => terminal.___primitive_switch({ + + /** + * Many possible continuations (from the perspective of initial = TERMINAL) + * + * From something, we arrived at some TERMINAL/INITIAL, which at its `.self`, holds a VERTEX. + * [ ? ] + * [--|--][--| ] <-- ref superposed with ref.self + * [ ? ] + */ + [RayType.VERTEX]: arbitrary_continuations, + + /** + * A possible continuation + * + * (INITIAL -> TERMINAL) + * (TERMINAL -> INITIAL) + */ + [boundary]: follow_direction, + [opposite(boundary)]: follow_direction, + + [RayType.REFERENCE]: dereference, + }); + + return initial.___primitive_switch({ + + /** + * VERTEX -> VERTEX + * TODO Could be an ignorant continuation (as in, the terminal does not have the initial vertex on its .initial). Or you could interpret this as saying, oh this should be a vertex, no information about the continuation definition in between? + * + * VERTEX -> TERMINAL + * If we're going in the terminal direction (from the perspective of the initial = VERTEX) + * [--|--][--| ] <-- (VERTEX -> TERMINAL) + * + * VERTEX -> INITIAL + * If we're going in the initial direction (from the perspective of the initial = VERTEX) + * [ |--][--|--] <-- (VERTEX -> INITIAL) + * + * VERTEX -> REFERENCE + * TODO ??? + */ + [RayType.VERTEX]: (initial) => dereference(ref.terminal), + + [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL)(ref.terminal), + [RayType.TERMINAL]: (initial) => boundary(RayType.TERMINAL)(ref.terminal), + + [RayType.REFERENCE]: dereference, + }); + } + next2 = Ray.___func(Ray.next2).as_method(this); + + static step = (ref: Ray) => { + const { initial } = ref; + } + step = (cases: { + [RayType.VERTEX]: (self: Ray) => Ray, + + CONTINUATION: (self: Ray) => Ray, + [RayType.REFERENCE]?: (self: Ray) => Ray }): Ray => { const { CONTINUATION } = cases; - const { initial } = this.self; - return initial.___primitive_switch({ + /** + * INITIAL <-> TERMINAL + * MANY INITIAL <-> VERTEX <-> MANY TERMINAL + * + */ + + // TODO: These cases should be implemented as a moving cursor/selection + return this.___primitive_switch({ [RayType.VERTEX]: cases[RayType.VERTEX], - [RayType.TERMINAL]: (self - // , disambiguate: { [RayType.INITIAL]: (), } + [RayType.TERMINAL]: (self// , disambiguate: { [RayType.INITIAL]: (), } + ) => CONTINUATION(self), + [RayType.INITIAL]: (self + // , disambiguate: { [RayType.INITIAL]: (), } ) => CONTINUATION(self), - [RayType.REFERENCE]: () => Ray.vertex(new Ray({ - initial: () => initial.self, // Dereference - terminal: initial._terminal // Pass terminal without evaluating - }).as_arbitrary()), + /** + * + * + * - Can be followed infinitely - if there's an orbit formed somewhere. + */ + [RayType.REFERENCE]: + /** + * Can be used to override default dereference behavior. + * + * TODO: This should probably be configurable on a more global setting. + */ + cases[RayType.REFERENCE] + ?? (() => Ray.vertex(() => this.self.self).as_reference()), // Dereference }) } @@ -245,10 +366,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence */ - static compose = Ray.___func(ref => ref.match({ + static compose = Ray.___func(ref => ref.step({ [RayType.VERTEX]: () => { throw new NotImplementedError(); }, CONTINUATION: (self): Ray => { - + throw new NotImplementedError(); } })); compose = Ray.compose.as_method(this); @@ -448,6 +569,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // } // }); + // terminal: this._terminal // Pass terminal without evaluating + return { /** @@ -499,91 +622,41 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? const method = Ray.___func(ref => { const { initial, terminal } = ref.self; - // const direction = terminal.type; - - // throw new NotImplementedError(`'${direction}'`); - return initial.___primitive_switch({ [RayType.VERTEX]: () => terminal.___primitive_switch({ - // TODO Could be an ignorant continuation (as in, the terminal does not have the initial vertex on its .initial). Or you could interpret this as saying, oh this should be a vertex, no information about the continuation definition in between? - [RayType.VERTEX]: (ref) => { throw new NotImplementedError(); }, - /** - * If we're going in the initial direction (from the perspective of the initial = VERTEX) - * [ |--][--|--] <-- terminal - */ [RayType.INITIAL]: (ref) => ref.self.___primitive_switch({ - // TODO REVERSE OF TERMINAL.. - // TODO: Implementation(ref) is probably concidently the same here.. - [RayType.TERMINAL]: (ref) => - // direction(ref) TODO - ref.self.initial.as_reference() - .___primitive_switch({ // TODO: This is applying the function again, should be separate? + [RayType.TERMINAL]: (ref) => ref.self.initial.as_reference() + .___primitive_switch({ // Found a next Vertex. [RayType.VERTEX]: (self) => self, + }), }), - /** - * If we're going in the terminal direction (from the perspective of the initial = VERTEX) - * [--|--][--| ] <-- terminal - */ [RayType.TERMINAL]: (ref) => ref.self.___primitive_switch({ - /** - * Many possible continuations (Vertical line is `ref.self`: Asking: 'What are the continuations at the terminal?`) - * - * ? - * [--|--][--| ]<-- ref superposed with ref.self - * ? - */ - [RayType.VERTEX]: () => { - throw new NotImplementedError() - }, - - // No continuations, either a self-reference, or different ways of halting. - [RayType.TERMINAL]: () => { throw new NotImplementedError() }, - // A possible continuation - [RayType.INITIAL]: (ref) => - // direction(ref) TODO - ref.self.terminal.as_reference() + [RayType.INITIAL]: (ref) => ref.self.terminal.as_reference() .___primitive_switch({ // TODO: This is applying the function again, should be separate? // Found a next Vertex. [RayType.VERTEX]: (self) => self, - // [RayType.VERTEX]: (self) => { throw new NotImplementedError(); }, // TODO: Same, but defined a step further // [RayType.TERMINAL]: () => Ray.None(), [RayType.TERMINAL]: () => { throw new NotImplementedError(); }, - // TODO: This switch could repeat infinitely, we need a way to hook into each step.. - [RayType.INITIAL]: () => { throw new NotImplementedError(); }, - - // TODO: Similar to Initial, probably follow the reference, possibly infintely... - [RayType.REFERENCE]: (ref) => { - // throw new NotImplementedError(`${ref.type}/${ref.self.type} - ${ref.any.js}/${ref.self.any.js}`); - // - // if (ref.self.type === RayType.VERTEX) - // return ref.self; - - throw new NotImplementedError(`${ref.type} ${ref.self.type}`); - } }), - // TODO: Possibly follow infintely - [RayType.REFERENCE]: (ref) => { throw new NotImplementedError(ref.self.type); } }), }) }) }).as_method; - // TODO Implemented as ___func, indicating terminal as the direction of next? as in 'this.next(this => this.self.terminal)' as default, basically, .next is generalizable to any function... - - return (ref: Ray) => method(ref)(step(ref)); // TODO: Merge __next into __func, make this cleaner... + return (ref: Ray) => method(ref)(step(ref)); } /** @@ -905,6 +978,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? push_back = (ray: Ray) => { throw new NotImplementedError(); } push_front = (ray: Ray) => { throw new NotImplementedError(); } + + // [index: number]: Ray; + // length: number; // // concat(...items: ConcatArray[]): Ray[]; From e9e52bad4c9dcc0d0437c71256a95e4c94b90924 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 15:05:03 +0100 Subject: [PATCH 073/138] 2024/01/16 - Iterating on some ideas to implement 'next' --- src/@orbitmines/explorer/Ray.spec.ts | 19 ++++--- src/@orbitmines/explorer/Ray.ts | 81 ++++++++-------------------- 2 files changed, 32 insertions(+), 68 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index eafe295..c310f19 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -26,7 +26,9 @@ describe("Ray", () => { const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); A.continues_with(B).continues_with(C); - + + // let pointer = A.step(Ray.directions.next(A)); + let pointer = new Ray({ initial: () => A, terminal: () => Ray.directions.next(A), @@ -40,7 +42,7 @@ describe("Ray", () => { expect(pointer.initial.type).toBe(RayType.VERTEX); expect(pointer.terminal.type).toBe(RayType.TERMINAL); - pointer = Ray.next2(pointer); + pointer = pointer.step(); /** * ______________ @@ -49,7 +51,8 @@ describe("Ray", () => { */ expect(pointer.initial.type).toBe(RayType.TERMINAL); expect(pointer.terminal.type).toBe(RayType.INITIAL); - pointer = Ray.next2(pointer); + + pointer = pointer.step(); /** * ____________ @@ -60,7 +63,7 @@ describe("Ray", () => { expect(pointer.terminal.type).toBe(RayType.VERTEX); expect(pointer.terminal.self.any.js).toBe('B'); - pointer = Ray.next2(pointer); + pointer = pointer.step(); /** * ____________ @@ -70,7 +73,7 @@ describe("Ray", () => { expect(pointer.initial.type).toBe(RayType.VERTEX); expect(pointer.terminal.type).toBe(RayType.TERMINAL); - pointer = Ray.next2(pointer); + pointer = pointer.step(); /** * ______________ @@ -80,7 +83,7 @@ describe("Ray", () => { expect(pointer.initial.type).toBe(RayType.TERMINAL); expect(pointer.terminal.type).toBe(RayType.INITIAL); - pointer = Ray.next2(pointer); + pointer = pointer.step(); /** * ____________ @@ -91,7 +94,7 @@ describe("Ray", () => { expect(pointer.terminal.type).toBe(RayType.VERTEX); expect(pointer.terminal.self.any.js).toBe('C'); - pointer = Ray.next2(pointer); + pointer = pointer.step(); /** * ____________ @@ -101,7 +104,7 @@ describe("Ray", () => { expect(pointer.initial.type).toBe(RayType.VERTEX); expect(pointer.terminal.type).toBe(RayType.TERMINAL); - pointer = Ray.next2(pointer); + pointer = pointer.step(); /** * _______ diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index a8ba92b..90b8a6a 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -192,6 +192,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return vertex.as_reference();//.continues_with(current.as_reference()); } + /** + * Can be used to override default dereference behavior. + * + * TODO: This should probably be configurable on a more global setting. + */ get dereference() { return this.self.self.as_reference(); } /** @@ -199,7 +204,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * TODO: switch/match Should be abstracted into Ray? */ - static next2 = (ref: Ray) => { + static step = (ref: Ray) => { const { initial } = ref; /** @@ -249,10 +254,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? [RayType.TERMINAL]: (initial) => Ray.directions.previous(terminal), })); - const found_vertex = (ref: Ray): Ray => { - throw new NotImplementedError(); - } - const boundary = (boundary: Boundary) => (terminal: Ray): Ray => terminal.___primitive_switch({ /** @@ -302,53 +303,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? [RayType.REFERENCE]: dereference, }); } - next2 = Ray.___func(Ray.next2).as_method(this); - - static step = (ref: Ray) => { - const { initial } = ref; - } - step = (cases: { - [RayType.VERTEX]: (self: Ray) => Ray, - - CONTINUATION: (self: Ray) => Ray, - - [RayType.REFERENCE]?: (self: Ray) => Ray - }): Ray => { - const { CONTINUATION } = cases; - - /** - * INITIAL <-> TERMINAL - * MANY INITIAL <-> VERTEX <-> MANY TERMINAL - * - */ - - // TODO: These cases should be implemented as a moving cursor/selection - return this.___primitive_switch({ - - [RayType.VERTEX]: cases[RayType.VERTEX], - - [RayType.TERMINAL]: (self// , disambiguate: { [RayType.INITIAL]: (), } - ) => CONTINUATION(self), - [RayType.INITIAL]: (self - // , disambiguate: { [RayType.INITIAL]: (), } - ) => CONTINUATION(self), + step= Ray.___func(Ray.step).as_method(this); - /** - * - * - * - Can be followed infinitely - if there's an orbit formed somewhere. - */ - [RayType.REFERENCE]: - /** - * Can be used to override default dereference behavior. - * - * TODO: This should probably be configurable on a more global setting. - */ - cases[RayType.REFERENCE] - ?? (() => Ray.vertex(() => this.self.self).as_reference()), // Dereference - - }) - } protected ___primitive_switch = (cases: SwitchCases): Ray => { const _case = cases[this.type]; @@ -366,13 +322,13 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence */ - static compose = Ray.___func(ref => ref.step({ - [RayType.VERTEX]: () => { throw new NotImplementedError(); }, - CONTINUATION: (self): Ray => { - throw new NotImplementedError(); - } - })); - compose = Ray.compose.as_method(this); + // static compose = Ray.___func(ref => ref.step({ + // [RayType.VERTEX]: () => { throw new NotImplementedError(); }, + // CONTINUATION: (self): Ray => { + // throw new NotImplementedError(); + // } + // })); + // compose = Ray.compose.as_method(this); // static equivalent2 = Ray.___func(ref => { // let { initial, terminal} = ref.self; @@ -577,6 +533,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] */ as_method: (ref: Ray): Method => (...any: Recursive): Ray => { + if (any === undefined || any.length === 0) + return step(ref); + // TODO: This can be much better... const first = (recursive?: Recursive): Ray | undefined => { if (recursive === undefined) return; @@ -601,10 +560,12 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (_first === undefined) return step(ref); - return step(new Ray({ + const pointer = new Ray({ initial: ref.as_arbitrary(), terminal: _first.as_arbitrary() - }).as_reference()); + }); + + return step(pointer); // TODO: ANY CASE // if (any.length === 1) { From 6e18ea2f5bc535c711d2f05fcf3176c288664144 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 15:37:41 +0100 Subject: [PATCH 074/138] 2024/01/16 - Iterating on some ideas to implement 'next' --- src/@orbitmines/explorer/Ray.spec.ts | 45 +++++++++++++++------------- src/@orbitmines/explorer/Ray.ts | 44 ++++++++++++++------------- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index c310f19..70e20cf 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -20,14 +20,14 @@ describe("Ray", () => { expect(method(a)(b).terminal.self.any.js).toBe('B'); expect(method(a)(b).type).toBe(RayType.VERTEX); }); - test(".next", () => { + test(".next()", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); A.continues_with(B).continues_with(C); - // let pointer = A.step(Ray.directions.next(A)); + // let pointer = A.step(Ray.directions.next()(A)); let pointer = new Ray({ initial: () => A, @@ -39,6 +39,9 @@ describe("Ray", () => { * [ |--] [--| ][ |--] [--| ][ |--] [--| ] * [--A--] [--B--] [--C--] */ + + expect(pointer.initial.self.any.js).toBe('A'); + expect(pointer.initial.type).toBe(RayType.VERTEX); expect(pointer.terminal.type).toBe(RayType.TERMINAL); @@ -115,33 +118,33 @@ describe("Ray", () => { // expect(pointer.terminal.type).toBe(RayType.TERMINAL); ?? expect(pointer.terminal.is_none()).toBe(true); }); - test("[A, B, C][.next, .previous]", () => { + test("[A, B, C][.next(), .previous()]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - expect(() => A.next).toThrow(); // TODO: Should be empty.. - expect(() => A.previous).toThrow(); // TODO: Should be empty.. + expect(() => A.next()).toThrow(); // TODO: Should be empty.. + expect(() => A.previous()).toThrow(); // TODO: Should be empty.. A.continues_with(B).continues_with(C); - expect(() => A.previous).toThrow(); // TODO: Should be ??.. - expect(() => A.next.next.next).toThrow(); // TODO: Should be ??.. + expect(() => A.previous()).toThrow(); // TODO: Should be ??.. + expect(() => A.next().next().next()).toThrow(); // TODO: Should be ??.. - expect(A.next.type).toBe(RayType.VERTEX); - // expect(current.next.any.js).toBe('B.#'); TODO, maybe the ref?? - expect(A.next.self.any.js).toBe('B'); + expect(A.next().type).toBe(RayType.VERTEX); + // expect(current.next().any.js).toBe('B.#'); TODO, maybe the ref?? + expect(A.next().self.any.js).toBe('B'); - expect(A.next.next.type).toBe(RayType.VERTEX); - expect(A.next.next.self.any.js).toBe('C'); + expect(A.next().next().type).toBe(RayType.VERTEX); + expect(A.next().next().self.any.js).toBe('C'); - expect(A.next.previous.self.any.js).toBe('A'); - expect(A.next.next.previous.self.any.js).toBe('B'); - expect(A.next.next.previous.previous.self.any.js).toBe('A'); - expect(A.next.previous.next.next.previous.self.any.js).toBe('B'); - expect(A.next.previous.next.next.previous.next.self.any.js).toBe('C'); + expect(A.next().previous().self.any.js).toBe('A'); + expect(A.next().next().previous().self.any.js).toBe('B'); + expect(A.next().next().previous().previous().self.any.js).toBe('A'); + expect(A.next().previous().next().next().previous().self.any.js).toBe('B'); + expect(A.next().previous().next().next().previous().next().self.any.js).toBe('C'); }); - // test("[A, [X, Y, Z].initial, B, C][.next, .previous]", () => { + // test("[A, [X, Y, Z].initial, B, C][.next(), .previous()]", () => { // /** // * | | // * |-- A --| |-- B --|-- C --| @@ -202,7 +205,7 @@ describe("Ray", () => { // } // )).toEqual([true, true, true]); // From the perspective of the 'terminal' it's ignorant of 'ret'. // - // expect(A.next.type).toBe(RayType.INITIAL); + // expect(A.next().type).toBe(RayType.INITIAL); // // /** // * | | @@ -287,11 +290,11 @@ describe("Ray", () => { // TODO async_generator / async_iterator / for await * }); - // test(".next(ref => .continues_with(.vertex.#))", () => { + // test(".next()(ref => .continues_with(.vertex.#))", () => { // let A = Ray.vertex().o({ js: 'A' }).as_reference(); // let B = Ray.vertex().o({ js: 'B'}).as_reference(); // - // B = A.next(ref => ref.continues_with(B)) + // B = A.next()(ref => ref.continues_with(B)) // // expect(B.type).toBe(RayType.VERTEX); // expect(B.self.any.js).toBe('B'); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 90b8a6a..0c24a9e 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -525,6 +525,14 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // } // }); + // const step: Implementation = (ref: Ray): Ray => { + // const pointer = new Ray({ + // initial: ref.as_arbitrary(), + // terminal: _first.as_arbitrary() + // }); + // } + + // terminal: this._terminal // Pass terminal without evaluating return { @@ -574,11 +582,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } } - /** - * TODO: next/continues_with/compose all generalizable?? - * - * @param direction Generalized as 'some function'. - */ static ___next = (step: Implementation) => { const method = Ray.___func(ref => { const { initial, terminal } = ref.self; @@ -590,26 +593,26 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? [RayType.INITIAL]: (ref) => ref.self.___primitive_switch({ [RayType.TERMINAL]: (ref) => ref.self.initial.as_reference() - .___primitive_switch({ - // Found a next Vertex. - [RayType.VERTEX]: (self) => self, + .___primitive_switch({ + // Found a next Vertex. + [RayType.VERTEX]: (self) => self, - }), + }), }), [RayType.TERMINAL]: (ref) => ref.self.___primitive_switch({ // A possible continuation [RayType.INITIAL]: (ref) => ref.self.terminal.as_reference() - .___primitive_switch({ // TODO: This is applying the function again, should be separate? - // Found a next Vertex. - [RayType.VERTEX]: (self) => self, + .___primitive_switch({ // TODO: This is applying the function again, should be separate? + // Found a next Vertex. + [RayType.VERTEX]: (self) => self, - // TODO: Same, but defined a step further - // [RayType.TERMINAL]: () => Ray.None(), - [RayType.TERMINAL]: () => { throw new NotImplementedError(); }, + // TODO: Same, but defined a step further + // [RayType.TERMINAL]: () => Ray.None(), + [RayType.TERMINAL]: () => { throw new NotImplementedError(); }, - }), + }), }), @@ -620,6 +623,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return (ref: Ray) => method(ref)(step(ref)); } + /** * Helper methods for commonly used directions * @@ -633,7 +637,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * .next */ - get next() { return Ray.___next(Ray.directions.next)(this); } + next = () => { return Ray.___next(Ray.directions.next)(this); } has_next = (step: Implementation = Ray.directions.next): boolean => step(this).is_none(); // @alias('end', 'result') last = (step: Implementation = Ray.directions.next): Ray => { @@ -643,7 +647,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * .previous */ - get previous(): Ray { return Ray.___next(Ray.directions.previous)(this); } + previous = (): Ray => { return Ray.___next(Ray.directions.previous)(this); } has_previous = (step: Implementation = Ray.directions.previous): boolean => this.has_next(step); first = (step: Implementation = Ray.directions.previous): Ray => this.last(step); @@ -733,7 +737,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // ___compute = () - *traverse(step: ((ref: Ray) => Ray) = ((ref): Ray => ref.next)): Generator { + *traverse(step: Implementation = Ray.directions.next): Generator { // TODO: Also to ___func?? if (this.type !== RayType.VERTEX) @@ -745,7 +749,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? yield current; try { - current = current.next; + current = current.next(); } catch (e) { // console.error('stopped traversal through implementation error...', e) break; // TODO: HACKY FOR NOW From 0975cdb572116e85ac78c3b84e2255ec03f1cec8 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 16:12:48 +0100 Subject: [PATCH 075/138] 2024/01/16 - Some bug somewhere.. --- src/@orbitmines/explorer/Ray.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 0c24a9e..a6c68f7 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -583,9 +583,18 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } static ___next = (step: Implementation) => { + const method = Ray.___func(ref => { const { initial, terminal } = ref.self; + // let pointer = ref.self.step(); + // let pointer2 = pointer.step(); + // let pointer3 = pointer2.step(); + + // throw new NotImplementedError(`[${initial.type}/${terminal.type}] -> [${pointer.initial.type}/${pointer.terminal.type}] -> [${pointer2.initial.type}/${pointer2.terminal.type}] -> [${pointer3.initial.type}/${pointer3.terminal.type}] -- ${initial.self.any.js}/${pointer3.initial.self.any.js}`); + + // return step2(ref); + return initial.___primitive_switch({ [RayType.VERTEX]: () => terminal.___primitive_switch({ @@ -637,7 +646,21 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * .next */ - next = () => { return Ray.___next(Ray.directions.next)(this); } + next = () => { + // let pointer = new Ray({ + // initial: () => this, + // terminal: () => Ray.directions.next(this), + // }); + // + // pointer = pointer.step().step(); + // + // if (pointer.terminal.type !== RayType.VERTEX) + // throw new NotImplementedError(pointer.terminal.type); + // + // return pointer.terminal; + + return Ray.___next(Ray.directions.next)(this); + } has_next = (step: Implementation = Ray.directions.next): boolean => step(this).is_none(); // @alias('end', 'result') last = (step: Implementation = Ray.directions.next): Ray => { From 11c00e8b55ac7a0231c2649664e5d8f61e016caa Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 16:35:54 +0100 Subject: [PATCH 076/138] 2024/01/16 - Quick fix --- src/@orbitmines/explorer/Ray.spec.ts | 155 +++++++++++++++++++-------- src/@orbitmines/explorer/Ray.ts | 50 +++++---- 2 files changed, 140 insertions(+), 65 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 70e20cf..94f2fc9 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -20,7 +20,7 @@ describe("Ray", () => { expect(method(a)(b).terminal.self.any.js).toBe('B'); expect(method(a)(b).type).toBe(RayType.VERTEX); }); - test(".next()", () => { + test("[A, B, C].next()", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); @@ -118,18 +118,77 @@ describe("Ray", () => { // expect(pointer.terminal.type).toBe(RayType.TERMINAL); ?? expect(pointer.terminal.is_none()).toBe(true); }); + test("[A, B, C].previous()", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + A.continues_with(B).continues_with(C); + + // let pointer = A.step(Ray.directions.next()(A)); + + let pointer = new Ray({ + initial: () => C, + terminal: () => Ray.directions.previous(C), + }); + + expect(pointer.initial.self.any.js).toBe('C'); + + expect(pointer.initial.type).toBe(RayType.VERTEX); + expect(pointer.terminal.type).toBe(RayType.INITIAL); + + pointer = pointer.step(); + + expect(pointer.initial.type).toBe(RayType.INITIAL); + expect(pointer.terminal.type).toBe(RayType.TERMINAL); + + pointer = pointer.step(); + + expect(pointer.initial.type).toBe(RayType.TERMINAL); + expect(pointer.terminal.type).toBe(RayType.VERTEX); + expect(pointer.terminal.self.any.js).toBe('B'); + + pointer = pointer.step(); + + expect(pointer.initial.type).toBe(RayType.VERTEX); + expect(pointer.terminal.type).toBe(RayType.INITIAL); + + pointer = pointer.step(); + + expect(pointer.initial.type).toBe(RayType.INITIAL); + expect(pointer.terminal.type).toBe(RayType.TERMINAL); + + pointer = pointer.step(); + + expect(pointer.initial.type).toBe(RayType.TERMINAL); + expect(pointer.terminal.type).toBe(RayType.VERTEX); + expect(pointer.terminal.self.any.js).toBe('A'); + + pointer = pointer.step(); + + expect(pointer.initial.type).toBe(RayType.VERTEX); + expect(pointer.terminal.type).toBe(RayType.INITIAL); + + pointer = pointer.step(); + + expect(pointer.initial.type).toBe(RayType.INITIAL); + // expect(pointer.terminal.type).toBe(RayType.TERMINAL); ?? + expect(pointer.terminal.is_none()).toBe(true); + }); test("[A, B, C][.next(), .previous()]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - expect(() => A.next()).toThrow(); // TODO: Should be empty.. - expect(() => A.previous()).toThrow(); // TODO: Should be empty.. + expect(A.next().is_none()).toBe(true); + expect(A.previous().is_none()).toBe(true); A.continues_with(B).continues_with(C); - expect(() => A.previous()).toThrow(); // TODO: Should be ??.. - expect(() => A.next().next().next()).toThrow(); // TODO: Should be ??.. + expect(A.next().is_none()).toBe(false); + expect(A.previous().is_none()).toBe(true); + + expect(A.next().next().next().is_none()).toBe(true); expect(A.next().type).toBe(RayType.VERTEX); // expect(current.next().any.js).toBe('B.#'); TODO, maybe the ref?? @@ -261,53 +320,55 @@ describe("Ray", () => { A.continues_with(B).continues_with(C); - expect(A.as_array().map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); // TODO: This may or may not be expected behavior, you could make a case for saying it should render both sides for .as_array. ??? - expect(C.as_array().map(ref => ref.self.any.js)).toEqual(['C']); - - expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.as_generator()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect(A.as_string()).toBe('A,B,C'); - - { + // expect(A.as_array().map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + // expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); // TODO: This may or may not be expected behavior, you could make a case for saying it should render both sides for .as_array. ??? + // expect(C.as_array().map(ref => ref.self.any.js)).toEqual(['C']); + // + // expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + // expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + // expect([...A.as_generator()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + // expect(A.as_string()).toBe('A,B,C'); + + // { + // + // const iterator = A.as_iterator(); + // + // let array: Ray[] = []; + // + // while (true) { + // let current = iterator.next(); + // if (current.done) + // break; + // + // array.push(current.value); + // } + // + // expect(array.map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + // + // } - const iterator = A.as_iterator(); - - let array: Ray[] = []; - - while (true) { - let current = iterator.next(); - if (current.done) - break; - - array.push(current.value); - } + // TODO async_generator / async_iterator / for await * + }); + test(".next", () => { + let A = Ray.vertex().o({ js: 'A' }).as_reference(); + let B = Ray.vertex().o({ js: 'B'}).as_reference(); - expect(array.map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + A.continues_with(B); - } + B = A.next(); - // TODO async_generator / async_iterator / for await * + expect(B.type).toBe(RayType.VERTEX); + expect(B.self.any.js).toBe('B'); + expect(B.self + .initial.self.initial + .any.js + ).toBe('A'); + expect(B.self + .initial.self.initial + .terminal.self.terminal + .any.js + ).toBe('B'); }); - // test(".next()(ref => .continues_with(.vertex.#))", () => { - // let A = Ray.vertex().o({ js: 'A' }).as_reference(); - // let B = Ray.vertex().o({ js: 'B'}).as_reference(); - // - // B = A.next()(ref => ref.continues_with(B)) - // - // expect(B.type).toBe(RayType.VERTEX); - // expect(B.self.any.js).toBe('B'); - // expect(B.self - // .initial.self.initial - // .any.js - // ).toBe('A'); - // expect(B.self - // .initial.self.initial - // .terminal.self.terminal - // .any.js - // ).toBe('B'); - // }); test(".vertex.#.equivalent(.vertex.#)", () => { let A = Ray.vertex().o({js: 'A'}) .as_reference().o({js: 'A.#'}); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index a6c68f7..eb2023d 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -229,8 +229,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ const next_pointer = (ref: Ray, terminal: Ray, next: Arbitrary) => new Ray({ - initial: terminal.as_arbitrary(), - vertex: ref.as_arbitrary(), + initial: () => terminal, + vertex: () => ref, terminal: next, }); @@ -569,8 +569,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return step(ref); const pointer = new Ray({ - initial: ref.as_arbitrary(), - terminal: _first.as_arbitrary() + initial: () => ref, + terminal: () => _first }); return step(pointer); @@ -647,19 +647,19 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * .next */ next = () => { - // let pointer = new Ray({ - // initial: () => this, - // terminal: () => Ray.directions.next(this), - // }); - // - // pointer = pointer.step().step(); - // - // if (pointer.terminal.type !== RayType.VERTEX) - // throw new NotImplementedError(pointer.terminal.type); - // - // return pointer.terminal; - - return Ray.___next(Ray.directions.next)(this); + let pointer = new Ray({ + initial: () => this, + terminal: () => Ray.directions.next(this), + }); + + pointer = pointer.step().step(); + + if (pointer.terminal.type !== RayType.VERTEX) + throw new NotImplementedError(pointer.terminal.type); + + return pointer.terminal; + + // return Ray.___next(Ray.directions.next)(this); } has_next = (step: Implementation = Ray.directions.next): boolean => step(this).is_none(); // @alias('end', 'result') @@ -670,7 +670,21 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * .previous */ - previous = (): Ray => { return Ray.___next(Ray.directions.previous)(this); } + previous = (): Ray => { + let pointer = new Ray({ + initial: () => this, + terminal: () => Ray.directions.previous(this), + }); + + pointer = pointer.step().step(); + + if (pointer.terminal.type !== RayType.VERTEX) + throw new NotImplementedError(pointer.terminal.type); + + return pointer.terminal; + + // return Ray.___next(Ray.directions.previous)(this); + } has_previous = (step: Implementation = Ray.directions.previous): boolean => this.has_next(step); first = (step: Implementation = Ray.directions.previous): Ray => this.last(step); From 3e4cad1bb79664dbb0bca08f8c08e23804fe9c10 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 16:47:19 +0100 Subject: [PATCH 077/138] 2024/01/16 - Tests for has_next/has_previous/first/last --- src/@orbitmines/explorer/Ray.spec.ts | 46 +++++++++++++++++++++++++++- src/@orbitmines/explorer/Ray.ts | 36 ++++++---------------- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 94f2fc9..4df0f7e 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -1,4 +1,5 @@ import {Ray, RayType} from "./Ray"; +import {previous} from "slate"; describe("Ray", () => { test(".___func(ref)", () => { @@ -175,6 +176,49 @@ describe("Ray", () => { // expect(pointer.terminal.type).toBe(RayType.TERMINAL); ?? expect(pointer.terminal.is_none()).toBe(true); }); + test("[A, B, C][.has_next(), .has_previous()]", () => { + const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); + const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); + const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); + + A.continues_with(B).continues_with(C); + + expect(A.has_next()).toBe(true); + expect(A.has_next(Ray.directions.next)).toBe(true); + expect(A.has_next(Ray.directions.previous)).toBe(false); + expect(A.has_previous()).toBe(false); + expect(A.has_previous(Ray.directions.previous)).toBe(false); + expect(A.has_previous(Ray.directions.next)).toBe(true); + + expect(B.has_next()).toBe(true); + expect(B.has_next(Ray.directions.next)).toBe(true); + expect(B.has_next(Ray.directions.previous)).toBe(true); + expect(B.has_previous()).toBe(true); + expect(B.has_previous(Ray.directions.previous)).toBe(true); + expect(B.has_previous(Ray.directions.next)).toBe(true); + + expect(C.has_next()).toBe(false); + expect(C.has_next(Ray.directions.next)).toBe(false); + expect(C.has_next(Ray.directions.previous)).toBe(true); + expect(C.has_previous()).toBe(true); + expect(C.has_previous(Ray.directions.previous)).toBe(true); + expect(C.has_previous(Ray.directions.next)).toBe(false); + }); + test("[A, B, C][.last(), .first()]", () => { + const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); + const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); + const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); + + A.continues_with(B).continues_with(C); + + expect(A.first().self.any.js).toBe('A'); + expect(B.first().self.any.js).toBe('A'); + expect(C.first().self.any.js).toBe('A'); + + expect(A.last().self.any.js).toBe('C'); + expect(B.last().self.any.js).toBe('C'); + expect(C.last().self.any.js).toBe('C'); + }); test("[A, B, C][.next(), .previous()]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); @@ -320,7 +364,7 @@ describe("Ray", () => { A.continues_with(B).continues_with(C); - // expect(A.as_array().map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect(A.as_array().map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); // expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); // TODO: This may or may not be expected behavior, you could make a case for saying it should render both sides for .as_array. ??? // expect(C.as_array().map(ref => ref.self.any.js)).toEqual(['C']); // diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index eb2023d..59430ca 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -646,10 +646,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * .next */ - next = () => { + next = (step: Implementation = Ray.directions.next) => { let pointer = new Ray({ initial: () => this, - terminal: () => Ray.directions.next(this), + terminal: () => step(this), }); pointer = pointer.step().step(); @@ -661,30 +661,16 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // return Ray.___next(Ray.directions.next)(this); } - has_next = (step: Implementation = Ray.directions.next): boolean => step(this).is_none(); + has_next = (step: Implementation = Ray.directions.next): boolean => this.next(step).is_some(); // @alias('end', 'result') last = (step: Implementation = Ray.directions.next): Ray => { - const next = step(this); - return next.is_none() ? next.last(step) : this; + const next = this.next(step); + return next.is_some() ? next.last(step) : this; } /** * .previous */ - previous = (): Ray => { - let pointer = new Ray({ - initial: () => this, - terminal: () => Ray.directions.previous(this), - }); - - pointer = pointer.step().step(); - - if (pointer.terminal.type !== RayType.VERTEX) - throw new NotImplementedError(pointer.terminal.type); - - return pointer.terminal; - - // return Ray.___next(Ray.directions.previous)(this); - } + previous = (step: Implementation = Ray.directions.previous): Ray => this.next(step); has_previous = (step: Implementation = Ray.directions.previous): boolean => this.has_next(step); first = (step: Implementation = Ray.directions.previous): Ray => this.last(step); @@ -785,12 +771,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? while (true) { yield current; - try { - current = current.next(); - } catch (e) { - // console.error('stopped traversal through implementation error...', e) - break; // TODO: HACKY FOR NOW - } + if (!current.has_next(step)) + break; + + current = current.next(); } } From ec67355c86d3f9ca490d1d6986a9c96f14f8ee6c Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 16:48:14 +0100 Subject: [PATCH 078/138] 2024/01/16 - Tests fixed for traverse --- src/@orbitmines/explorer/Ray.spec.ts | 50 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 4df0f7e..8080bb0 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -365,31 +365,31 @@ describe("Ray", () => { A.continues_with(B).continues_with(C); expect(A.as_array().map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - // expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); // TODO: This may or may not be expected behavior, you could make a case for saying it should render both sides for .as_array. ??? - // expect(C.as_array().map(ref => ref.self.any.js)).toEqual(['C']); - // - // expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - // expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - // expect([...A.as_generator()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - // expect(A.as_string()).toBe('A,B,C'); - - // { - // - // const iterator = A.as_iterator(); - // - // let array: Ray[] = []; - // - // while (true) { - // let current = iterator.next(); - // if (current.done) - // break; - // - // array.push(current.value); - // } - // - // expect(array.map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - // - // } + expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); // TODO: This may or may not be expected behavior, you could make a case for saying it should render both sides for .as_array. ??? + expect(C.as_array().map(ref => ref.self.any.js)).toEqual(['C']); + + expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.as_generator()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect(A.as_string()).toBe('A,B,C'); + + { + + const iterator = A.as_iterator(); + + let array: Ray[] = []; + + while (true) { + let current = iterator.next(); + if (current.done) + break; + + array.push(current.value); + } + + expect(array.map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + + } // TODO async_generator / async_iterator / for await * }); From 017bd8c915296c0cb7387cb7fe07b5ae612c7e79 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 16:49:29 +0100 Subject: [PATCH 079/138] 2024/01/16 - Remove import --- src/@orbitmines/explorer/Ray.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 8080bb0..c8d176c 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -1,5 +1,4 @@ import {Ray, RayType} from "./Ray"; -import {previous} from "slate"; describe("Ray", () => { test(".___func(ref)", () => { From 8cc6a67a14fc8544bf1bad32b22b44c1427db53d Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 16:59:50 +0100 Subject: [PATCH 080/138] 2024/01/16 - .dereference tests --- src/@orbitmines/explorer/Ray.spec.ts | 11 +++++ src/@orbitmines/explorer/Ray.ts | 65 +++------------------------- 2 files changed, 18 insertions(+), 58 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index c8d176c..88fcaa5 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -493,6 +493,17 @@ describe("Ray", () => { test(".as_arbitrary", () => { expect(Ray.vertex().o({ js: 'A' }).as_arbitrary()().any.js).toBe('A'); }); + test(".dereference", () => { + const A = Ray.vertex( + Ray.vertex().o({ js: "A.vertex" }).as_arbitrary() + ).o({ js: 'A' }).as_reference(); + + expect(A.dereference.self.any.js).toBe('A.vertex'); + expect(A.as_reference().dereference.self.any.js).toBe('A'); + expect(A.as_reference().as_reference().dereference.dereference.self.any.js).toBe('A'); + expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.self.any.js).toBe('A'); + expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.dereference.self.any.js).toBe('A.vertex'); + }); test(".o", () => { const ray = Ray.vertex().o({ a: 'b', diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 59430ca..817fac9 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -145,6 +145,13 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? is_some = (): boolean => !this.is_none(); + /** + * Can be used to override default dereference behavior. + * + * TODO: This should probably be configurable on a more global setting. + */ + get dereference() { return this.self.self.as_reference(); } + /** [ ] */ static None = () => new Ray({ }).o({ }); /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { // /** [?????] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }); @@ -192,13 +199,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return vertex.as_reference();//.continues_with(current.as_reference()); } - /** - * Can be used to override default dereference behavior. - * - * TODO: This should probably be configurable on a more global setting. - */ - get dereference() { return this.self.self.as_reference(); } - /** * * @@ -582,57 +582,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } } - static ___next = (step: Implementation) => { - - const method = Ray.___func(ref => { - const { initial, terminal } = ref.self; - - // let pointer = ref.self.step(); - // let pointer2 = pointer.step(); - // let pointer3 = pointer2.step(); - - // throw new NotImplementedError(`[${initial.type}/${terminal.type}] -> [${pointer.initial.type}/${pointer.terminal.type}] -> [${pointer2.initial.type}/${pointer2.terminal.type}] -> [${pointer3.initial.type}/${pointer3.terminal.type}] -- ${initial.self.any.js}/${pointer3.initial.self.any.js}`); - - // return step2(ref); - - return initial.___primitive_switch({ - [RayType.VERTEX]: () => terminal.___primitive_switch({ - - - [RayType.INITIAL]: (ref) => ref.self.___primitive_switch({ - - [RayType.TERMINAL]: (ref) => ref.self.initial.as_reference() - .___primitive_switch({ - // Found a next Vertex. - [RayType.VERTEX]: (self) => self, - - }), - }), - - [RayType.TERMINAL]: (ref) => ref.self.___primitive_switch({ - - // A possible continuation - [RayType.INITIAL]: (ref) => ref.self.terminal.as_reference() - .___primitive_switch({ // TODO: This is applying the function again, should be separate? - // Found a next Vertex. - [RayType.VERTEX]: (self) => self, - - // TODO: Same, but defined a step further - // [RayType.TERMINAL]: () => Ray.None(), - [RayType.TERMINAL]: () => { throw new NotImplementedError(); }, - - }), - - }), - - }) - }) - }).as_method; - - return (ref: Ray) => method(ref)(step(ref)); - } - - /** * Helper methods for commonly used directions * From da6e0333144ac4317721f4d8d66c3ffe07554f54 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 17:34:04 +0100 Subject: [PATCH 081/138] 2024/01/16 - Add older helper methods: .of_length, .at, .permutation & tests for .permutation --- src/@orbitmines/explorer/Ray.spec.ts | 80 +++++++++++++++++++++ src/@orbitmines/explorer/Ray.ts | 102 +++++++++++++++------------ 2 files changed, 138 insertions(+), 44 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 88fcaa5..99a41fa 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -218,6 +218,86 @@ describe("Ray", () => { expect(B.last().self.any.js).toBe('C'); expect(C.last().self.any.js).toBe('C'); }); + test("[A, B, C][.at()]", () => { + const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); + const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); + const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); + + A.continues_with(B).continues_with(C); + + expect(A.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); + expect(A.at(-100).is_none()).toBe(true); + expect(A.at(-1).is_none()).toBe(true); + expect(A.at(0).self.any.js).toBe('A'); + expect(A.at(1).self.any.js).toBe('B'); + expect(A.at(2).self.any.js).toBe('C'); + expect(A.at(3).is_none()).toBe(true); + expect(A.at(100).is_none()).toBe(true); + expect(A.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); + + expect(B.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); + expect(B.at(-100).is_none()).toBe(true); + expect(B.at(-2).is_none()).toBe(true); + expect(B.at(-1).self.any.js).toBe('A'); + expect(B.at(0).self.any.js).toBe('B'); + expect(B.at(1).self.any.js).toBe('C'); + expect(B.at(2).is_none()).toBe(true); + expect(B.at(100).is_none()).toBe(true); + expect(B.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); + + expect(C.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); + expect(C.at(-100).is_none()).toBe(true); + expect(C.at(-3).is_none()).toBe(true); + expect(C.at(-2).self.any.js).toBe('A'); + expect(C.at(-1).self.any.js).toBe('B'); + expect(C.at(0).self.any.js).toBe('C'); + expect(C.at(1).is_none()).toBe(true); + expect(C.at(100).is_none()).toBe(true); + expect(C.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); + }); + test(".permutation", () => { + const A = Ray.permutation(0, 3); + const B = Ray.permutation(1, 3); + const C = Ray.permutation(2, 3); + + expect(A.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); + expect(A.at(-100).is_none()).toBe(true); + expect(A.at(-1).is_none()).toBe(true); + + expect(A.at(0).is_some()).toBe(true); + expect(A.at(1).is_some()).toBe(true); + expect(A.at(2).is_some()).toBe(true); + + expect(A.at(3).is_none()).toBe(true); + expect(A.at(100).is_none()).toBe(true); + expect(A.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); + + + expect(B.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); + expect(B.at(-100).is_none()).toBe(true); + expect(B.at(-2).is_none()).toBe(true); + + expect(B.at(-1).is_some()).toBe(true); + expect(B.at(0).is_some()).toBe(true); + expect(B.at(1).is_some()).toBe(true); + + expect(B.at(2).is_none()).toBe(true); + expect(B.at(100).is_none()).toBe(true); + expect(B.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); + + + expect(C.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); + expect(C.at(-100).is_none()).toBe(true); + expect(C.at(-3).is_none()).toBe(true); + + expect(C.at(-2).is_some()).toBe(true); + expect(C.at(-1).is_some()).toBe(true); + expect(C.at(0).is_some()).toBe(true); + + expect(C.at(1).is_none()).toBe(true); + expect(C.at(100).is_none()).toBe(true); + expect(C.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); + }); test("[A, B, C][.next(), .previous()]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 817fac9..48f701a 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -184,8 +184,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); - - // as_option = (): Ray => Option.Some(this); as_arbitrary = (): Arbitrary => () => this; as_vertex = (): Ray => { @@ -519,22 +517,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? ): { as_method: ArbitraryMethod } { - // const func = new Ray({ - // terminal: (): Ray => { - // - // } - // }); - - // const step: Implementation = (ref: Ray): Ray => { - // const pointer = new Ray({ - // initial: ref.as_arbitrary(), - // terminal: _first.as_arbitrary() - // }); - // } - - - // terminal: this._terminal // Pass terminal without evaluating - return { /** @@ -611,16 +593,17 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // return Ray.___next(Ray.directions.next)(this); } has_next = (step: Implementation = Ray.directions.next): boolean => this.next(step).is_some(); - // @alias('end', 'result') + // @alias('end', 'result', 'back') last = (step: Implementation = Ray.directions.next): Ray => { const next = this.next(step); return next.is_some() ? next.last(step) : this; } /** - * .previous + * .previous (Just .next with a `Ray.directions.previous` default) */ previous = (step: Implementation = Ray.directions.previous): Ray => this.next(step); has_previous = (step: Implementation = Ray.directions.previous): boolean => this.has_next(step); + // @alias('beginning', 'front') first = (step: Implementation = Ray.directions.previous): Ray => this.last(step); // TODO: I Don't like this name, but it needs to get across that any equivalency, or any equivalency check for that necessarily, is local. And I want more equivalences, I run more of this method. @@ -651,20 +634,58 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return copy; } - // export const at = (index: number, of: number, value: any = undefined): Arbitrary> => { -// return Arbitrary.Fn(() => length(of, value).resolve().at_terminal(index)); -// } -// - // step = this.at; ??? - at = (steps: number | Ray | Arbitrary): Ray => { throw new NotImplementedError(); } - // -// export const permutation = (permutation: number | undefined, of: number): Arbitrary> => at( -// // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) -// permutation ?? 0, -// // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. -// permutation === undefined ? 1 : of -// ) -// + /** + * TODO - Better 'value' here. (Use JS.Any??) + * + * TODO: All these should accept Ray values. + * + * of_length, since .length is reserved by JavaScript. + */ + static of_length = (of: number, value: any = undefined): Ray => { + let ret: Ray | undefined; + let current: Ray | undefined; + // TODO: Actual good implementation: Should be lazy + for (let i = 0; i < of; i++) { + const vertex = Ray.vertex().o({js: value}).as_reference(); + + if (!ret) { + current = ret = vertex; + } else { + current = current?.continues_with(vertex); + } + } + + if (!ret) + return Ray.None(); + + return ret; + } + static at = (index: number, of: number, value: any = undefined): Ray => { + return Ray.of_length(of, value).at(index); + } + static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( + // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) + permutation ?? 0, + // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. + permutation === undefined ? 1 : of + ) + + at = (steps: number | Ray | Arbitrary): Ray => { + if (!JS.is_number(steps)) + throw new NotImplementedError('Not yet implemented for Rays.'); + + // TODO: Actual good implementation - also doesn't support modular like this + const array = [...this.traverse( + steps < 0 ? Ray.directions.previous : Ray.directions.next + )]; + + steps = Math.abs(steps); + + return array.length > steps && steps >= 0 ? ( + array[steps] ?? Ray.None() // TODO FIX: Probably a JavaScript quirck with some weird numbers, just failsafe to None. + ) : Ray.None(); + } + // export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' @@ -723,7 +744,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (!current.has_next(step)) break; - current = current.next(); + current = current.next(step); } } @@ -910,6 +931,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; } + // TODO: These are just (.back/.front) + .continues_with ?? push_back = (ray: Ray) => { throw new NotImplementedError(); } push_front = (ray: Ray) => { throw new NotImplementedError(); } @@ -1092,18 +1114,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * - * Important to remember this is just one particular structure to which it can be mapped, there are probably many (infinitely?) others. + * Important to remember this is just one particular structure to which it can be mapped, there are probably many (TODO infinitely?) others. * * Not to be considered as a perfect mapping of JavaScript functionality - merely a practical one. */ - - // Number: (number: number) => typeof number, - // Function: (func: ParameterlessFunction) => typeof func, - - // Number: (number: number) => number, - // Function: (func: ParameterlessFunction) => func, - - export namespace JS { export const Boolean = (boolean: boolean): Ray => { // |-false->-true-| (could of course also be reversed) From f5bd3120afcd4553177c374cf48de608191f68c3 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 17:37:42 +0100 Subject: [PATCH 082/138] 2024/01/16 - Already had .of_length as .size --- src/@orbitmines/explorer/Ray.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 48f701a..aa65639 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -172,15 +172,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? ___empty_initial = () => new Ray({ vertex: Ray.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); ___empty_terminal = () => new Ray({ vertex: Ray.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); - static size = (of: number, value: any = undefined): Ray => { - let current = Ray.vertex().as_reference(); // TODO; This sort of thing should be lazy - for (let i = 0; i < of; i++) { - current = current.continues_with(Ray.vertex(JS.Any(value).as_arbitrary()).as_reference()); - } - - return current; - } - /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); @@ -639,9 +630,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * TODO: All these should accept Ray values. * - * of_length, since .length is reserved by JavaScript. + * .size, since .length is reserved by JavaScript. */ - static of_length = (of: number, value: any = undefined): Ray => { + // @alias('length', 'of_length') + static size = (of: number, value: any = undefined): Ray => { let ret: Ray | undefined; let current: Ray | undefined; // TODO: Actual good implementation: Should be lazy @@ -661,7 +653,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return ret; } static at = (index: number, of: number, value: any = undefined): Ray => { - return Ray.of_length(of, value).at(index); + return Ray.size(of, value).at(index); } static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) From 29338c3befe0472eb57839096902469da2cfcaf1 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 17:39:33 +0100 Subject: [PATCH 083/138] 2024/01/16 - Permutation comment --- src/@orbitmines/explorer/Ray.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index aa65639..67d1f7c 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -655,6 +655,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? static at = (index: number, of: number, value: any = undefined): Ray => { return Ray.size(of, value).at(index); } + /** + * Just uses length/size for permutation. TODO: More complex permutation implementation should follow at some point. (@see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=One%20of%20them%20could%20even%20be%20putting%20both%20our%20points%20on%20our%20selection for an example) + */ static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) permutation ?? 0, From 1d2fe2c76dabdda347acf8e58d4560aaa5707bbc Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 17:40:52 +0100 Subject: [PATCH 084/138] 2024/01/16 - Permutation comment --- src/@orbitmines/explorer/Ray.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 67d1f7c..431c540 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -631,6 +631,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * TODO: All these should accept Ray values. * * .size, since .length is reserved by JavaScript. + * TODO: .size could be more tensor-like, arbitrary lengths.. */ // @alias('length', 'of_length') static size = (of: number, value: any = undefined): Ray => { From e265a853a72c2ce71346067ee9e31592b6d6855c Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 16 Jan 2024 23:42:01 +0100 Subject: [PATCH 085/138] 2024/01/16 - Refactoring, some tests, after this is done need a much better interface setup --- src/@orbitmines/explorer/Ray.spec.ts | 107 ++++++---- src/@orbitmines/explorer/Ray.ts | 151 +++++++++----- .../explorer/debug/DebugCanvas.tsx | 12 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 192 ++++++++++++++++-- 4 files changed, 352 insertions(+), 110 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 99a41fa..4021ecd 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -20,6 +20,18 @@ describe("Ray", () => { expect(method(a)(b).terminal.self.any.js).toBe('B'); expect(method(a)(b).type).toBe(RayType.VERTEX); }); + test("[A, B, C].copy", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + A.continues_with(B).continues_with(C); + + expect(() => A.copy()).toThrow(); + // const copy = A.copy(); + // expect(A.has_previous()).toBe(false); + // expect(copy.has_previous()).toBe(false); + }); test("[A, B, C].next()", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); @@ -404,22 +416,66 @@ describe("Ray", () => { // // // }); - // test(".as_vertex", () => { - // const initial = Ray.terminal().o({js: 'A'}).as_reference().o({js: 'A.#'}); - // const terminal= Ray.initial().o({js: 'B'}).as_reference().o({js: 'B.#'}); - // - // initial.self = terminal.as_arbitrary(); - // terminal.self = initial.as_arbitrary(); - // - // const as_vertex = initial.as_vertex(); - // expect(as_vertex.self.any.js).toBe('B'); - // }); - test(".#.equivalent(.#)", () => { + test(".as_vertex", () => { + let A = Ray.terminal().o({js: 'A'}).as_reference().o({js: 'A.#'}); + // const B= Ray.initial().o({js: 'B'}).as_reference().o({js: 'B.#'}); + + // initial.self = terminal.self.as_arbitrary(); + // terminal.self = initial.self.as_arbitrary(); + + A = A.as_vertex(); + + // expect(A.self.any.js).toBe('A'); + expect(A.self.self.any.js).toBe('A'); + // expect(A.self.self.self.any.js).toBe('A'); + expect(A.self.self.self.self.any.js).toBe('A'); + }); + test(".None.#.equivalent(.None.#)", () => { + const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. + const B = Ray.None().o({ js: 'B' }).as_reference(); + + expect(A.is_none()).toBe(true); + expect(A.self.any.js).toBe('A'); + expect(A.self.self.any.js).toBe('A'); + expect(A.self.self.self.any.js).toBe('A'); + + expect(B.is_none()).toBe(true); + expect(B.self.any.js).toBe('B'); + expect(B.self.self.any.js).toBe('B'); + expect(B.self.self.self.any.js).toBe('B'); + + const ret = A.equivalent(B); + + expect(A.is_none()).toBe(false); + expect(A.self.any.js).toBe('A'); + expect(A.self.self.any.js).toBe('B'); + expect(A.self.self.self.any.js).toBe('A'); + + expect(B.is_none()).toBe(false); + expect(B.self.any.js).toBe('B'); + expect(B.self.self.any.js).toBe('A'); + expect(B.self.self.self.any.js).toBe('B'); + }); + test(".None.#.equivalent(.vertex.#)", () => { + const A = Ray.None().as_reference(); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + + // const ret = A.equivalent(B); + + // expect() + }); + test(".vertex.#.equivalent(.vertex.#)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + expect(A.any.js).toBe('A.#'); + expect(B.any.js).toBe('B.#'); + const ret = A.equivalent(B); + expect(A.self.any.js).toBe('A'); + expect(B.self.any.js).toBe('B'); + expect(A.self.self.any.js).toBe('B'); expect(B.self.self.any.js).toBe('A'); @@ -492,35 +548,6 @@ describe("Ray", () => { .any.js ).toBe('B'); }); - test(".vertex.#.equivalent(.vertex.#)", () => { - let A = Ray.vertex().o({js: 'A'}) - .as_reference().o({js: 'A.#'}); - let B = Ray.vertex().o({js: 'B'}) - .as_reference().o({js: 'B.#'}); - - expect(A.any.js).toBe('A.#'); - expect(B.any.js).toBe('B.#'); - - let ref = A.equivalent(B); - - expect(ref.self.initial).toBe(A); - expect(ref.self.terminal).toBe(B); - expect(ref.self.initial.any.js).toBe('A.#'); - expect(ref.self.terminal.any.js).toBe('B.#'); - - expect(A.self.any.js).toBe('A'); - expect(B.self.any.js).toBe('B'); - - expect(A.self.self).toBe(B.self); - expect(B.self.self).toBe(A.self); - expect(A.self.self.any.js).toBe('B'); - expect(B.self.self.any.js).toBe('A'); - - expect(B.self.self.self).toBe(B.self); - expect(B.self.self.self.self).toBe(A.self); - expect(B.self.self.self.any.js).toBe('B'); - expect(B.self.self.self.self.any.js).toBe('A'); - }); test(".vertex.#.continues_with(.vertex.#)", () => { let A = Ray.vertex().o({ js: 'A' }).as_reference(); let B = Ray.vertex().o({ js: 'B'}).as_reference(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 431c540..948944c 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -139,6 +139,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * Tries for "global coherence" - since we probably can't actually do that, practically this just means self-reference, were no change is assumed... + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. */ static is_orbit = (a: Ray, b: Ray) => a === b; // is, ..., appears equal. protected self_reference = () => this; @@ -152,6 +154,20 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ get dereference() { return this.self.self.as_reference(); } + /** + * Places the current structure inside a new non-ignorant vertex. + */ + as_vertex = (): Ray => { + const vertex = Ray.vertex(this.self.as_arbitrary()); + const current = this.self.self; + + this.self.self = vertex.as_arbitrary(); + + // TODO: Disregards anything on this.self.self?? - or not with current?? + + return vertex.as_reference();//.continues_with(current.as_reference()); + } + /** [ ] */ static None = () => new Ray({ }).o({ }); /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { // /** [?????] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }); @@ -177,17 +193,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_arbitrary = (): Arbitrary => () => this; - as_vertex = (): Ray => { - const vertex = Ray.vertex(this.self.as_arbitrary()); - const current = this.self.self; - - this.self.self = vertex.as_arbitrary(); - - // TODO: Disregards anything on this.self.self?? - or not with current?? - - return vertex.as_reference();//.continues_with(current.as_reference()); - } - /** * * @@ -305,31 +310,45 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // @alias('merge, 'continues_with', 'compose') /** - * Compose as "Equivalence at Continuations" + * Compose as "Equivalence at Continuations": (can usually be done in parallel - not generally) + * - `A.compose(B)` = `(A.TERMINAL).equivalent(B.INITIAL)` + * - `A.compose(B).compose(C)` = `(A.TERMINAL).equivalent(B.INITIAL) & (B.TERMINAL).equivalent(C.INITIAL)` * - * `A.compose(B).compose(C)` = `A.` + * Another interesting connection: + * - `A.compose(B).compose(C)` = `(A.equivalent(B).equivalent(C)).dereference.(MISSING ALL FUNC).compose` * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence + * @see "Continuations as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence */ - // static compose = Ray.___func(ref => ref.step({ - // [RayType.VERTEX]: () => { throw new NotImplementedError(); }, - // CONTINUATION: (self): Ray => { - // throw new NotImplementedError(); - // } - // })); - // compose = Ray.compose.as_method(this); - - // static equivalent2 = Ray.___func(ref => { - // let { initial, terminal} = ref.self; - // - // return Ray.vertex(initial).compose(terminal); - // }); - // equivalent2 = Ray.compose(this); + static compose = Ray.___func(ref => { + + }); + compose = Ray.compose.as_method(this); + + /** + * Equivalence as "Composing Vertices" + * - `A.equivalent(B)` = `A.as_vertex().compose(B.as_vertex())` + * - `A.equivalent(B).equivalent(C)` = `A.as_vertex().compose(B.as_vertex()).compose(C.as_vertex())` + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies + */ + static equivalent2 = Ray.___func(ref => { + let { initial, terminal} = ref.self; + initial.as_vertex().compose(terminal.as_vertex()); + return ref; + }); + equivalent2 = Ray.equivalent2.as_method(this); + + + /** + * Equivalence in this context, is best understood as the drawing of the line between two things. And ensures that the line can be found on the `.vertex/.self` of those two things. (Albeit in an arbitrary place on it). + */ static equivalent= Ray.___func(ref => { let { initial, terminal } = ref.self; + // TODO: Can just move the terminal which holds the oointer to the boundary + // TODO: IS THIS EVEN HOW THIS SHOULD WORK?? - Now just takes the pointer and assumes that as its own @@ -344,6 +363,18 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * initial.self.self / terminal.self.self - The direction which defines what it's connected to (could be ignorant) */ + if (initial.self.is_none() && terminal.self.is_none()) { + /** + * Basically turns an Orbit which repeats on every step, to one which repeats every 2 steps. + * Or in textual terms something like: `(A.self = A) | (B.self = B)` to `(A.self = B) | (B.self = A)`. + */ + + initial.self.self = terminal.self.as_arbitrary(); + terminal.self.self = initial.self.as_arbitrary(); + + return ref; + } + if (initial.self.is_none() || terminal.self.is_none()) { /** * Basically when [].self === [].self.self - See "{Ray.is_orbit}". @@ -610,7 +641,28 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? get count(): Ray { throw new NotImplementedError() } // TODO; Could return the ignorant reference to both instances, or just the result., .. - copy = (): Ray => { throw new NotImplementedError() } + + /** + * TODO: Need more control over the (non-/)lazyness of copy. + */ + copy = (): Ray => { + throw new NotImplementedError(); + + // const copy = new Ray({ + // initial: this.self._initial().as_reference().none_or(ref => ref.copy()).as_arbitrary(), + // vertex: this.self._vertex().as_reference().none_or(ref => ref.copy()).as_arbitrary(), + // }).o({ ___dirty_copy_buffer: {} }); + // // copy._initial = () => copy.any.___dirty_copy_buffer._initial ??= this.self._initial().as_reference().copy(); + // // copy._vertex = () => copy.any.___dirty_copy_buffer._vertex ??= this.self._vertex().as_reference().copy(); + // // copy._terminal = () => copy.any.___dirty_copy_buffer._terminal ??= this.self._terminal().as_reference().copy(); + // + // + // // TODO: Doesn't copy .any + // + // return copy.as_reference(); + } + + none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); // @alias('converse', 'opposite', 'swap') get reverse(): Ray { @@ -658,6 +710,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } /** * Just uses length/size for permutation. TODO: More complex permutation implementation should follow at some point. (@see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=One%20of%20them%20could%20even%20be%20putting%20both%20our%20points%20on%20our%20selection for an example) + * + * @see "Combinatorics as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Combinatorics%20%2D%20Combinatorics%20as%20Equivalence */ static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) @@ -744,6 +798,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } } + *traverse2(step: Implementation = Ray.directions.next): Generator { + + } + /** * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. */ @@ -848,7 +906,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? static POSITION_OF_DOOM = [0, 100, 0] // TODO: Abstract away as compilation - get render_options(): Required { + render_options = (Interface: Ray): Required => { return ({ position: this.self.any.position @@ -860,14 +918,17 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? this.self.any.scale ?? (this.is_none() ? 1.5 : 1.5), color: - this.self.any.color - ?? (this.is_none() ? 'red' : { - [RayType.VERTEX]: 'orange', - [RayType.TERMINAL]: '#FF5555', - [RayType.INITIAL]: '#5555FF', - [RayType.REFERENCE]: '#555555', - }[this.type] - ) + (Ray.is_orbit(Interface.any.selection.self, this.self) && Interface.any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) + : ( + this.self.any.color + ?? (this.is_none() ? 'red' : { + [RayType.VERTEX]: 'orange', + [RayType.TERMINAL]: '#FF5555', + [RayType.INITIAL]: '#5555FF', + [RayType.REFERENCE]: '#555555', + }[this.type] + ) + ) }); } @@ -1091,22 +1152,13 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } -// force = (): any => self.match({ -// Some: (a) => a, -// None: () => { throw new Error('Expected Some(value) to be present but found None.') } -// }); -// + // default = (fn: () => any): any => self.match({ // Some: (a) => a, // None: () => fn() // }) // -// none_or = (or: (obj: any) => any): Option => { -// return self.match({ -// Some: (some: any) => Option.Some(or(some)), -// None: () => Ray.None -// }) -// } + /** * @@ -1173,6 +1225,7 @@ export namespace JS { export const Generator = (generator: Generator): Ray => JS.Iterable(generator); + // TODO Could have parallel threads in general. // export const AsyncGenerator = (generator: AsyncGenerator): Ray => { // // [ |--] // return JS.Iterable(generator); diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index 7ba374b..a6f4838 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -13,10 +13,10 @@ import _ from "lodash"; // TODO: It's, rende rboth draw equivalence, then ignore the difference from either perspective or take some middle thing. - Line from both ends, also vertex? (or take the pos, take the x from one/other, y from the other/..) // TODO: Could be a function on Ray (any func really) -export const Render = ({ ray }: { ray: Ray }) => { - const initial: Required = ray.self.initial.as_reference().render_options; - const vertex: Required = ray.render_options; - const terminal: Required = ray.self.terminal.as_reference().render_options; +export const Render = ({ ray, Interface }: { ray: Ray, Interface: Ray }) => { + const initial: Required = ray.self.initial.as_reference().render_options(Interface); + const vertex: Required = ray.render_options(Interface); + const terminal: Required = ray.self.terminal.as_reference().render_options(Interface); switch (ray.type) { case RayType.REFERENCE: @@ -131,7 +131,7 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { console.log(`rays.length at pos=[${Interface.any.selection.render_options.position}]: ${Interface.any.rays.filter((ray: Ray) => _.isEqual( Interface.any.selection.render_options.position, - ray.render_options.position + ray.render_options(Interface).position ) ).length} / ${Interface.any.rays.length}`) console.log('ref', Interface.any.selection) @@ -166,7 +166,7 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { {/*{Interface.any.rays.map((ray: Ray) => )}*/} - {Interface.any.rays.map((ray: Ray) => )} + {Interface.any.rays.map((ray: Ray) => )} } diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 0d4401b..3a40a91 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -1,4 +1,4 @@ -import React, {useRef, useState} from "react"; +import React, {useEffect, useRef, useState} from "react"; import IEventListener from "../../js/react/IEventListener"; import {VisualizationCanvas} from "../../explorer/Visualization"; import { @@ -144,15 +144,15 @@ const ___index = (ray: Ray): number => { } } -export const Render2 = ({ ray, show = { initial: true, terminal: true } }: { ray: Ray, index: number, show?: { initial: boolean, terminal: boolean } }) => { +export const Render2 = ({ ray, Interface, show = { initial: true, terminal: true } }: { ray: Ray, Interface: Ray, index: number, show?: { initial: boolean, terminal: boolean } }) => { const index = ___index(ray); let added = [15 * index, 60 * index, 0]; - const initial: Required = ray.self.initial.as_reference().render_options; + const initial: Required = ray.self.initial.as_reference().render_options(Interface); initial.position = add_(initial.position, added); - const vertex: Required = ray.render_options; + const vertex: Required = ray.render_options(Interface); vertex.position = add_(vertex.position, added); - const terminal: Required = ray.self.terminal.as_reference().render_options; + const terminal: Required = ray.self.terminal.as_reference().render_options(Interface); terminal.position = add_(terminal.position, added); switch (ray.type) { @@ -268,14 +268,14 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { const { selection, rays } = Interface.any; - const current = Interface.any.selection.render_options; + const current = Interface.any.selection.render_options(Interface); const next = Ray.vertex().o2({ initial: { position: add_(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, vertex: { index: Interface.any.selection.self.any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, terminal: { position: add_(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } }).as_reference().o({ - ...selection.as_reference().render_options, + ...selection.as_reference().render_options(Interface), position: add(selection.any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) }); @@ -294,10 +294,10 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { Interface.any.selection = Interface.any.selection.pop(); Interface.any.selection.o({ - position: Interface.any.selection.render_options.position + position: Interface.any.selection.render_options(Interface).position }); // TODO, Same with this. Interface.any.selection.self.terminal.o({ - position: add(Interface.any.selection.render_options.position, [space_between, 0, 0]), scale, color: 'orange' + position: add(Interface.any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { @@ -346,10 +346,10 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { combo: "/", global: true, label: "", onKeyDown: () => { console.log('---------') console.log(`Debugging: ${Interface.any.selection.self.label} (type=${Interface.any.selection.type})`) - console.log(`rays.length at pos=[${Interface.any.selection.render_options.position}]: ${Interface.any.rays.filter((ray: Ray) => + console.log(`rays.length at pos=[${Interface.any.selection.render_options(Interface).position}]: ${Interface.any.rays.filter((ray: Ray) => _.isEqual( Interface.any.selection.render_options.position, - ray.render_options.position + ray.render_options(Interface).position ) ).length} / ${Interface.any.rays.length}`) console.log('ref', Interface.any.selection) @@ -389,13 +389,13 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { {/*{Interface.any.rays.map((ray: Ray) => )}*/} - {Interface.any.rays.map((ray: Ray) => )} + {Interface.any.rays.map((ray: Ray) => )} - {Interface.any.rays.map((ray: Ray, index: number) => )} + {Interface.any.rays.map((ray: Ray, index: number) => )} @@ -403,7 +403,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { - {Interface.any.rays.map((ray: Ray, index: number) => )} + {Interface.any.rays.map((ray: Ray, index: number) => )} @@ -444,6 +444,168 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { } +export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { + const ref = useRef(); + const hotkeyConfig = useHotkeys(); + + const { + gl: renderer, + camera, + scene, + raycaster + } = useThree(); + + const space_between = 20 * scale; + + const [Interface] = useState(Ray.vertex().o({ + selection: Ray.vertex().o2({ + initial: { position: [-space_between, 0, 0], scale, color: 'orange' }, + vertex: { index: 0, position: [0, 0, 0], scale, color: 'orange' }, + terminal: { position: [space_between, 0, 0 ], scale, color: 'orange' }, + }).as_reference().o({ + position: [0, 0, 0], + scale, + rotation: [0, 0, Math.PI / 6 ], + color: '#555555' + }), + rays: [] as Ray[], + stats: false, + cursor: { + tick: false + }, + controls: Ray.vertex().o({ + hotkeys: [ + { + combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { + const { selection, rays } = Interface.any; + + const current = Interface.any.selection.render_options(Interface); + + const next = Ray.vertex().o2({ + initial: { position: add_(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, + vertex: { index: Interface.any.selection.self.any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, + terminal: { position: add_(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } + }).as_reference().o({ + ...selection.as_reference().render_options(Interface), + position: add(selection.any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) + }); + + Interface.any.selection = selection.continues_with(next); + Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.any.traversed = true; + return ray.as_reference(); + }); + + } + }, + { + combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { + if (Interface.any.rays.length === 0) + return; + + Interface.any.selection = Interface.any.selection.pop(); + Interface.any.selection.o({ + position: Interface.any.selection.render_options(Interface).position + }); // TODO, Same with this. + Interface.any.selection.self.terminal.o({ + position: add(Interface.any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' + }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. + + Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.any.traversed = true; + return ray.as_reference(); + }); + + if (Interface.any.length === 0) { + Interface.any.selection.any.position = [0, 0, 0] + return; + } + } + }, + { + combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { + const { selection, rays } = Interface.any; + + Interface.any.rays = rays.flatMap((ray: Ray) => [ + ray, + // Ray.js("A").as_reference().o({ + // // ...ray.o, + // position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]) + // }), + // Ray.js("A").as_reference().o({ + // // ...ray.o, + // position: ray.any.position, + // rotation: [0, 0, Math.PI / 2] + // }), + // Ray.js("A").as_reference().o({ + // // ...ray.o, + // position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]), + // rotation: [0, 0, Math.PI / 2] + // }) + ]); + + // Chyp_naieve_pass.any.selection = Chyp_naieve_pass; + + // selection.o({...selection.o, position: add(selection.any.position ?? [0, 0, 0], [0, i * 2, 0])}) + + // selection.continues_with( + + // ); + } + }, + { + combo: "/", global: true, label: "", onKeyDown: () => { + console.log('---------') + console.log(`Debugging: ${Interface.any.selection.self.label} (type=${Interface.any.selection.type})`) + console.log(`rays.length at pos=[${Interface.any.selection.render_options(Interface).position}]: ${Interface.any.rays.filter((ray: Ray) => + _.isEqual( + Interface.any.selection.render_options(Interface).position, + ray.render_options(Interface).position + ) + ).length} / ${Interface.any.rays.length}`) + console.log('ref', Interface.any.selection) + console.log('ref.self', Interface.any.selection.self) + + const debug: DebugResult = {}; + Interface.any.selection.self.debug(debug); + console.log('ref.debug', debug); + Interface.any.rays.forEach((ray: Ray) => ray.debug(debug)); + console.log('rays.debug', debug); + } + }, + { + combo: "f3", global: true, label: "Show stats Panel", onKeyDown: (e) => { + e.preventDefault(); + Interface.any.stats = !Interface.any.stats; + } + }, + ] as HotkeyConfig[] + }) + })); + + // useEffect(() => { + // TODO: Eventually goes over maximum size of react-debug callstack when updates each frame like this. + hotkeyConfig.set(...Interface.any.controls.any.hotkeys); + // }, [Interface.any.controls.any.hotkeys]); + + useEffect(() => { + + setInterval(() => { + Interface.any.cursor.tick = !Interface.any.cursor.tick; + + // TODO THIS NEEDS TO BE EASIER + }, 500); // TODO; On react reload interval is not destroyed + }, []); + + return <> + {Interface.any.stats ? : <>} + + + + {Interface.any.rays.map((ray: Ray) => )} + +} + // const Interface = () => { // // TODO: Direct call to rerender on change, now there's lag // @@ -501,7 +663,7 @@ const ChypCanvas = ( - + } From 9d151978051f259afd2e294965ad790159b85f86 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 13:17:34 +0100 Subject: [PATCH 086/138] 2024/01/17 - Some minor doc changes from thoughts last night --- src/@orbitmines/explorer/Ray.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 948944c..202c884 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -325,7 +325,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? compose = Ray.compose.as_method(this); /** - * Equivalence as "Composing Vertices" + * Equivalence as "Composing Vertices": "TODO: Is this right?: Equivalence at Continuations, inside a Vertex, is parallel composition" * - `A.equivalent(B)` = `A.as_vertex().compose(B.as_vertex())` * - `A.equivalent(B).equivalent(C)` = `A.as_vertex().compose(B.as_vertex()).compose(C.as_vertex())` * @@ -644,8 +644,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * TODO: Need more control over the (non-/)lazyness of copy. + * + * - The problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. + * + * - Additionally, a copy necessarily has some non-redundancy to it: + * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy */ + // @alias('duplicate') copy = (): Ray => { + // return this.self.as_reference(); // Copies the reference? throw new NotImplementedError(); // const copy = new Ray({ From a527feefa6bcfb4f8060df521001e28fbe575830 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 13:25:20 +0100 Subject: [PATCH 087/138] 2024/01/17 - Some minor doc changes from thoughts last night --- src/@orbitmines/explorer/Ray.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 202c884..ede5311 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -329,6 +329,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * - `A.equivalent(B)` = `A.as_vertex().compose(B.as_vertex())` * - `A.equivalent(B).equivalent(C)` = `A.as_vertex().compose(B.as_vertex()).compose(C.as_vertex())` * + * An equivalence is best understood as the drawing of a single line between two things. Where those two things might have arbitrary structure around them, but we're not checking the (non-)existence of that structure. And thus: + * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. (or: Changes of an equivalence are only applied locally, which could have global effects, but this isn't necessarily obvious). + * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies */ static equivalent2 = Ray.___func(ref => { From 0c4533bdf381392a4713d05e572495a3b1e2767b Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 14:39:27 +0100 Subject: [PATCH 088/138] 2024/01/17 - .equivalent --- src/@orbitmines/explorer/Ray.spec.ts | 58 +++++++++++++++++++------ src/@orbitmines/explorer/Ray.ts | 65 ++++++++++++---------------- 2 files changed, 71 insertions(+), 52 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 4021ecd..924160f 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -434,6 +434,9 @@ describe("Ray", () => { const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. const B = Ray.None().o({ js: 'B' }).as_reference(); + expect(A.type).toBe(RayType.VERTEX); + expect(B.type).toBe(RayType.VERTEX); + expect(A.is_none()).toBe(true); expect(A.self.any.js).toBe('A'); expect(A.self.self.any.js).toBe('A'); @@ -444,7 +447,10 @@ describe("Ray", () => { expect(B.self.self.any.js).toBe('B'); expect(B.self.self.self.any.js).toBe('B'); - const ret = A.equivalent(B); + A.equivalent2(B); + + expect(A.type).toBe(RayType.REFERENCE); // Turns A into a reference to B. + expect(B.type).toBe(RayType.REFERENCE); // Turns B into a reference to A. expect(A.is_none()).toBe(false); expect(A.self.any.js).toBe('A'); @@ -456,30 +462,36 @@ describe("Ray", () => { expect(B.self.self.any.js).toBe('A'); expect(B.self.self.self.any.js).toBe('B'); }); - test(".None.#.equivalent(.vertex.#)", () => { - const A = Ray.None().as_reference(); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - - // const ret = A.equivalent(B); - - // expect() - }); test(".vertex.#.equivalent(.vertex.#)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + expect(A.type).toBe(RayType.VERTEX); + expect(B.type).toBe(RayType.VERTEX); expect(A.any.js).toBe('A.#'); expect(B.any.js).toBe('B.#'); - const ret = A.equivalent(B); + expect(A.is_none()).toBe(false); + expect(A.dereference.is_none()).toBe(true); - expect(A.self.any.js).toBe('A'); - expect(B.self.any.js).toBe('B'); + expect(B.is_none()).toBe(false); + expect(B.dereference.is_none()).toBe(true); - expect(A.self.self.any.js).toBe('B'); - expect(B.self.self.any.js).toBe('A'); + let ret = A.equivalent2(B); + expect(A.type).toBe(RayType.VERTEX); + expect(B.type).toBe(RayType.VERTEX); + expect(A.self.type).toBe(RayType.VERTEX); + expect(B.self.type).toBe(RayType.VERTEX); + + expect(A.is_none()).toBe(false); + expect(A.self.any.js).toBe('A'); + expect(A.self.self.any.js).toBe('B'); expect(A.self.self.self.any.js).toBe('A'); + + expect(B.is_none()).toBe(false); + expect(B.self.any.js).toBe('B'); + expect(B.self.self.any.js).toBe('A'); expect(B.self.self.self.any.js).toBe('B'); expect(ret.self.initial.any.js).toBe('A.#'); @@ -492,6 +504,24 @@ describe("Ray", () => { expect(ret.self.terminal.self.self.any.js).toBe('A'); expect(ret.self.terminal.self.self.self.any.js).toBe('B'); }); + test(".None.#.equivalent(.None.#) ;.equivalent(.None.#)", () => { + const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. + const B = Ray.None().o({ js: 'B' }).as_reference(); + const C = Ray.None().o({ js: 'C' }).as_reference(); + + let ret = A.equivalent2(B); + + ret = B.equivalent2(C); + + }); + test(".None.#.equivalent(.vertex.#)", () => { + const A = Ray.None().as_reference(); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + + // const ret = A.equivalent(B); + + // expect() + }); test("[A, B, C][.as_array, ...]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index ede5311..116ef3f 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -151,6 +151,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * Can be used to override default dereference behavior. * * TODO: This should probably be configurable on a more global setting. + * + * TODO: Difference between this.self and this.self.self.as_reference is??? */ get dereference() { return this.self.self.as_reference(); } @@ -337,16 +339,36 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? static equivalent2 = Ray.___func(ref => { let { initial, terminal} = ref.self; - initial.as_vertex().compose(terminal.as_vertex()); + /** + * The simplest case, is where both sides are only aware of themselves (on .vertex). The only thing we need to do is turn an Orbit, to an Orbit which repeats every 2 steps, the intermediate step being the other thing. + * + * Or in textual terms something like: + * - A single Orbit: `(A.self = A) | (B.self = B)` (i.e. A.is_none && B.is_none) + * - To: `(A.self = B) | (B.self = A)` + * + * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. + */ + const ignorant_equivalence = (): Ray => { + initial.self.vertex = terminal.self.as_arbitrary(); + terminal.self.vertex = initial.self.as_arbitrary(); + return ref; + } + + // 2x Ray.None -> Turn into 2 empty references, referencing each-other. + if (initial.is_none() && terminal.is_none()) + return ignorant_equivalence(); + + // Two structures, which have `ref.self = Ray.None` -> Turn into two structures referencing each-other. + if (initial.dereference.is_none() && terminal.dereference.is_none()) + return ignorant_equivalence(); + + throw new NotImplementedError(`[${initial.type}] .equiv [${terminal.type}]`); + // initial.as_vertex().compose(terminal.as_vertex()); return ref; }); equivalent2 = Ray.equivalent2.as_method(this); - - /** - * Equivalence in this context, is best understood as the drawing of the line between two things. And ensures that the line can be found on the `.vertex/.self` of those two things. (Albeit in an arbitrary place on it). - */ static equivalent= Ray.___func(ref => { let { initial, terminal } = ref.self; @@ -354,42 +376,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO: IS THIS EVEN HOW THIS SHOULD WORK?? - Now just takes the pointer and assumes that as its own - // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? - /** - * The type of equivalence so [initial.type, terminal.type], doesn't matter for us to do this equivalence. So we don't need an "initial.___primitive_switch + terminal.___primitive_switch" here, but instead we go directly to the things we're referencing: {initial.self} & {terminal.self} (TODO: is this actually the case??) - * - * initial / terminal - Two ('references') to things we're equivalencing - * initial.self / terminal.self - Two things/.../abstract directions/rays we actually want to connect - * initial.self.self / terminal.self.self - The direction which defines what it's connected to (could be ignorant) - */ - - if (initial.self.is_none() && terminal.self.is_none()) { - /** - * Basically turns an Orbit which repeats on every step, to one which repeats every 2 steps. - * Or in textual terms something like: `(A.self = A) | (B.self = B)` to `(A.self = B) | (B.self = A)`. - */ - - initial.self.self = terminal.self.as_arbitrary(); - terminal.self.self = initial.self.as_arbitrary(); - - return ref; - } - - if (initial.self.is_none() || terminal.self.is_none()) { - /** - * Basically when [].self === [].self.self - See "{Ray.is_orbit}". - * - * TODO: "This is basically already the case, they're already equivalent. - Could take this to mean that we want a degree of separation between them??" - */ - throw new PreventsImplementationBug(`Not expecting empty equivalences (for now)`); //TODO ?? What to do with these? - } - - if (initial.type === RayType.REFERENCE || terminal.type === RayType.REFERENCE) - throw new PreventsImplementationBug(`Not expecting references? ${initial.type}/${terminal.type}`); // TODO REMOVE - if (initial.self.self.is_none() && terminal.self.self.is_none()) { // throw new NotImplementedError('a'); /** From 9124c7509828a5bfd9bc0ce4045be5adbe4d29b2 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 15:54:07 +0100 Subject: [PATCH 089/138] 2024/01/17 - .as_terminal / .as_initial --- src/@orbitmines/explorer/Ray.spec.ts | 124 ++++++++++++++++++++++----- src/@orbitmines/explorer/Ray.ts | 61 +++++++++++-- 2 files changed, 157 insertions(+), 28 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 924160f..b23da4d 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -416,20 +416,6 @@ describe("Ray", () => { // // // }); - test(".as_vertex", () => { - let A = Ray.terminal().o({js: 'A'}).as_reference().o({js: 'A.#'}); - // const B= Ray.initial().o({js: 'B'}).as_reference().o({js: 'B.#'}); - - // initial.self = terminal.self.as_arbitrary(); - // terminal.self = initial.self.as_arbitrary(); - - A = A.as_vertex(); - - // expect(A.self.any.js).toBe('A'); - expect(A.self.self.any.js).toBe('A'); - // expect(A.self.self.self.any.js).toBe('A'); - expect(A.self.self.self.self.any.js).toBe('A'); - }); test(".None.#.equivalent(.None.#)", () => { const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. const B = Ray.None().o({ js: 'B' }).as_reference(); @@ -504,15 +490,113 @@ describe("Ray", () => { expect(ret.self.terminal.self.self.any.js).toBe('A'); expect(ret.self.terminal.self.self.self.any.js).toBe('B'); }); - test(".None.#.equivalent(.None.#) ;.equivalent(.None.#)", () => { - const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. - const B = Ray.None().o({ js: 'B' }).as_reference(); - const C = Ray.None().o({ js: 'C' }).as_reference(); + // test(".None.#.equivalent(.None.#) ;.equivalent(.None.#)", () => { + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + // + // let ret = A.equivalent2(B); + // + // ret = B.equivalent2(C); + // + // }); + test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - let ret = A.equivalent2(B); + A.equivalent2(B); + + const terminal = A.as_terminal(); + + expect(terminal.type).toBe(RayType.TERMINAL); + + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); + + /** + * terminal_vertex = A + * initial_vertex = B + * + * Since we're at the terminal, and reversing direction, that gives 'terminal_vertex' first, then 'initial_vertex'. + */ + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + + /** + * These should keep looping... + * TODO: Better test helper for this + */ + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + }); + test("(A:vertex.# = B:vertex.#) ; B.as_terminal", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + + A.equivalent2(B); - ret = B.equivalent2(C); + const terminal = B.as_terminal(); + expect(terminal.type).toBe(RayType.TERMINAL); + + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + + /** + * These should keep looping... + * TODO: Better test helper for this + */ + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + }); + test("(A:vertex.# = B:vertex.#) ; A.as_initial", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + + A.equivalent2(B); + + const initial = A.as_initial(); + + expect(initial.type).toBe(RayType.INITIAL); + + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); + + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + + /** + * These should keep looping... + * TODO: Better test helper for this + */ + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + }); + test("(A:vertex.# = B:vertex.#) ; B.as_initial", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + + A.equivalent2(B); + + const initial = B.as_initial(); + + expect(initial.type).toBe(RayType.INITIAL); + + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + + /** + * These should keep looping... + * TODO: Better test helper for this + */ + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); }); test(".None.#.equivalent(.vertex.#)", () => { const A = Ray.None().as_reference(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 116ef3f..88cd19c 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -170,6 +170,51 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return vertex.as_reference();//.continues_with(current.as_reference()); } + /** + * Moves `this.self` and `this.self.self` to a new line. + * + * [ |--] this.self ----- this.self.self [--|--] + * ______ (<- initial pointer) + */ + as_initial = (): Ray => { + const [terminal_vertex, initial_vertex] = this.___as_vertices(); + + // TODO BETTER DEBUG + initial_vertex.o({ js: 'initial_vertex' }).continues_with(terminal_vertex.o({ js: 'terminal_vertex' })) + + return initial_vertex.self.initial.as_reference(); + } + /** + * Moves `this.self` and `this.self.self` to a new line. + * + * [ |--] this.self.self ----- this.self [--|--] + * _____ (<- terminal pointer) + */ + as_terminal = (): Ray => { + const [initial_vertex, terminal_vertex] = this.___as_vertices(); + + return ( + initial_vertex.o({ js: 'initial_vertex' }).continues_with(terminal_vertex.o({ js: 'terminal_vertex' })) // TODO BETTER DEBUG + .self.terminal.as_reference() + ) + } + private ___as_vertices = (): [Ray, Ray] => { + if (!Ray.is_orbit(this.self, this.self.self.self)) + throw new PreventsImplementationBug('Is there a use-case for this? Probably not?'); //TODO + + // TODO NOTE: THE ORDER OF `this.self` first matters here. + return [this.self.___as_vertex2(), this.___as_vertex2()]; + } + private ___as_vertex2 = (): Ray => { + return this.self.___ignorantly_equivalent(Ray.vertex().as_reference()); + } + private ___ignorantly_equivalent = (ref: Ray): Ray => { + this.self = ref.as_arbitrary(); + ref.self = this.as_arbitrary(); + + return ref; + } + /** [ ] */ static None = () => new Ray({ }).o({ }); /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { // /** [?????] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }); @@ -193,6 +238,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); + // TODO: Difference between () => this & this.as_arbitrary , relevant for lazy/modular/ignorant structures etc.. as_arbitrary = (): Arbitrary => () => this; /** @@ -327,7 +373,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? compose = Ray.compose.as_method(this); /** - * Equivalence as "Composing Vertices": "TODO: Is this right?: Equivalence at Continuations, inside a Vertex, is parallel composition" + * Equivalence as "Composing Vertices": "TODO: Is this right?: Equivalence at Continuations, inside a Vertex, is parallel composition, from the perspective of the usual direction defined at the Vertex (not generally parallel)" * - `A.equivalent(B)` = `A.as_vertex().compose(B.as_vertex())` * - `A.equivalent(B).equivalent(C)` = `A.as_vertex().compose(B.as_vertex()).compose(C.as_vertex())` * @@ -349,8 +395,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. */ const ignorant_equivalence = (): Ray => { - initial.self.vertex = terminal.self.as_arbitrary(); - terminal.self.vertex = initial.self.as_arbitrary(); + initial.self.___ignorantly_equivalent(terminal.self); return ref; } @@ -362,7 +407,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (initial.dereference.is_none() && terminal.dereference.is_none()) return ignorant_equivalence(); - throw new NotImplementedError(`[${initial.type}] .equiv [${terminal.type}]`); + + + throw new NotImplementedError(`[${initial.type}] .equiv [${terminal.type}] / ${Ray.is_orbit(initial.self.self.self.self, terminal.self.self.self)}`); // initial.as_vertex().compose(terminal.as_vertex()); return ref; @@ -626,6 +673,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO; in the case of a list, each individually, again, additional structure... } // TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? + + // TODO: Whether the thing is referenced on the vertex: do their vertices have some connection onm this direction? is_equivalent = (b: Ray): boolean => { return false; } // TODOl: Current references assume you can't go inside vertex.. // TODO implement .not?? @@ -797,10 +846,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } } - *traverse2(step: Implementation = Ray.directions.next): Generator { - - } - /** * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. */ From 52ce84e7d3e5a02dc484643f407e515d8f5ba4ce Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 16:16:16 +0100 Subject: [PATCH 090/138] 2024/01/17 - .as_terminal / .as_initial through .equivalence + tests --- src/@orbitmines/explorer/Ray.spec.ts | 23 +++++++++++++---------- src/@orbitmines/explorer/Ray.ts | 21 +++++++++++++++++---- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index b23da4d..b1ae6f3 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -490,16 +490,19 @@ describe("Ray", () => { expect(ret.self.terminal.self.self.any.js).toBe('A'); expect(ret.self.terminal.self.self.self.any.js).toBe('B'); }); - // test(".None.#.equivalent(.None.#) ;.equivalent(.None.#)", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - // - // let ret = A.equivalent2(B); - // - // ret = B.equivalent2(C); - // - // }); + test("(A:vertex.# = B:vertex.# = C:vertex.#)", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + // const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); + + A.equivalent2(B); + // C.equivalent2(D); + + // A.equivalent2(D); + A.equivalent2(C); + + }); test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 88cd19c..51c21a1 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -111,6 +111,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** [--|--] */ is_vertex = (): boolean => !this.is_initial() && !this.is_terminal(); /** [?-| ] */ is_terminal = (): boolean => this.is_some() && this.self.terminal.is_none(); /** [ | ] */ is_reference = (): boolean => this.is_initial() && this.is_terminal(); + /** [?-| ] or [ |-?] */ is_boundary = (): boolean => !this.is_reference() && (this.is_initial() || this.is_terminal()); // TODO: IS !This.references necessary? get type(): RayType { /** [ | ] */ if (this.is_reference()) return RayType.REFERENCE; @@ -188,7 +189,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * Moves `this.self` and `this.self.self` to a new line. * * [ |--] this.self.self ----- this.self [--|--] - * _____ (<- terminal pointer) + * _____ (<- terminal pointer) */ as_terminal = (): Ray => { const [initial_vertex, terminal_vertex] = this.___as_vertices(); @@ -407,10 +408,22 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (initial.dereference.is_none() && terminal.dereference.is_none()) return ignorant_equivalence(); + if ( + (initial.is_vertex() && terminal.is_boundary()) + || (terminal.is_vertex() && initial.is_boundary()) + ) { + throw new NotImplementedError(`Parallel composition: TODO`); + } - - throw new NotImplementedError(`[${initial.type}] .equiv [${terminal.type}] / ${Ray.is_orbit(initial.self.self.self.self, terminal.self.self.self)}`); - // initial.as_vertex().compose(terminal.as_vertex()); + /** + * - Splits the 'initial' side's vertex, into an iterable one, and returns a pointer to the initial side of that iterator. + * + * - Similarly, we do the opposite for the terminal, returning the terminal side of that iterator. + * + * - Then we're left with the 'beginning' of one iterator, and the 'end' of the other. And the only thing that's left to do, is draw a simple (ignorant) equivalence between the two. (Basically call this function again, and call {ignorant_equivalence}). + * TODO: This could also be a line with some debug information. + */ + initial.as_initial().equivalent2(terminal.as_terminal()); return ref; }); From c6d564e838f9e91b47f92a0996b60a25350f17c4 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 16:36:53 +0100 Subject: [PATCH 091/138] 2024/01/17 - Remove continues_with dependence --- src/@orbitmines/explorer/Ray.spec.ts | 176 +++++++++++++++------------ src/@orbitmines/explorer/Ray.ts | 20 ++- 2 files changed, 113 insertions(+), 83 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index b1ae6f3..8e372e9 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -338,18 +338,7 @@ describe("Ray", () => { expect(A.next().previous().next().next().previous().self.any.js).toBe('B'); expect(A.next().previous().next().next().previous().next().self.any.js).toBe('C'); }); - // test("[A, [X, Y, Z].initial, B, C][.next(), .previous()]", () => { - // /** - // * | | - // * |-- A --| |-- B --|-- C --| - // * | \ | - // * |-- X --| - // * | \ | - // * |-- Y --| - // * | \ | - // * |-- Z --| - // * | \ | (Destroys the '\' connections) TODO: This should be optional/more complexly constructed - // */ + // test("[A, B, C], [X, Y, Z] ; A.terminal = Y.initial", () => { // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); @@ -358,64 +347,93 @@ describe("Ray", () => { // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); // + // A.continues_with(B).continues_with(C); // X.continues_with(Y).continues_with(Z); // - // const ret = A.continues_with(X.self.initial.as_reference()); - // - // /** - // * | - // * |-- A --| - // * | \ <-- '\' is 'ret' - // * |-- X --| - // * | \ - // * |-- Y --| - // * | \ - // * |-- Z --| - // * | \ - // */ - // expect(ret.type).toBe(RayType.INITIAL); - // expect(ret.self.terminal.as_reference().is_none()).toBe(false); - // expect([...ret.self.terminal.as_reference()].map( - // return_ref => return_ref.type - // )).toEqual([RayType.VERTEX, RayType.VERTEX, RayType.VERTEX]); - // expect([...ret.self.terminal.as_reference()].map( - // return_ref => return_ref.self.type - // )).toEqual([RayType.TERMINAL, RayType.TERMINAL, RayType.TERMINAL]); - // expect([...ret.self.terminal.as_reference()].map( - // return_ref => { - // const return_vertex = return_ref.self; - // const terminal = return_vertex.self; - // const continued_vertex = terminal.initial; - // - // return continued_vertex.any.js; - // } - // )).toEqual(['X', 'Y', 'Z']); - // expect([...ret.self.terminal.as_reference()].map( - // return_ref => { - // const vertex = return_ref.self; - // const terminal = vertex.self; - // - // return terminal.self.as_reference().is_none(); - // } - // )).toEqual([true, true, true]); // From the perspective of the 'terminal' it's ignorant of 'ret'. - // - // expect(A.next().type).toBe(RayType.INITIAL); - // - // /** - // * | | - // * |-- A --| |-- B --|-- C --| - // * | | - // * |-- X --| - // * | | - // * |-- Y --| - // * | | - // * |-- Z --| - // * | | - // */ - // ret.continues_with(B).continues_with(C); - // + // A.self.terminal.as_reference().equivalent2(Y.self.initial.as_reference()); // + // expect(Y.previous()).toBe('?') // }); + test("[A, [X, Y, Z].initial, B, C][.next(), .previous()]", () => { + // /** + // * | | + // * |-- A --| |-- B --|-- C --| + // * | \ | + // * |-- X --| + // * | \ | + // * |-- Y --| + // * | \ | + // * |-- Z --| + // * | \ | (Destroys the '\' connections) TODO: This should be optional/more complexly constructed + // */ + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + // + // const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); + // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); + // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); + // + // X.continues_with(Y).continues_with(Z); + + // const ret = A.continues_with(X.self.initial.as_reference()); + + + + // /** + // * | + // * |-- A --| + // * | \ <-- '\' is 'ret' + // * |-- X --| + // * | \ + // * |-- Y --| + // * | \ + // * |-- Z --| + // * | \ + // */ + // expect(ret.type).toBe(RayType.INITIAL); + // expect(ret.self.terminal.as_reference().is_none()).toBe(false); + // expect([...ret.self.terminal.as_reference()].map( + // return_ref => return_ref.type + // )).toEqual([RayType.VERTEX, RayType.VERTEX, RayType.VERTEX]); + // expect([...ret.self.terminal.as_reference()].map( + // return_ref => return_ref.self.type + // )).toEqual([RayType.TERMINAL, RayType.TERMINAL, RayType.TERMINAL]); + // expect([...ret.self.terminal.as_reference()].map( + // return_ref => { + // const return_vertex = return_ref.self; + // const terminal = return_vertex.self; + // const continued_vertex = terminal.initial; + // + // return continued_vertex.any.js; + // } + // )).toEqual(['X', 'Y', 'Z']); + // expect([...ret.self.terminal.as_reference()].map( + // return_ref => { + // const vertex = return_ref.self; + // const terminal = vertex.self; + // + // return terminal.self.as_reference().is_none(); + // } + // )).toEqual([true, true, true]); // From the perspective of the 'terminal' it's ignorant of 'ret'. + // + // expect(A.next().type).toBe(RayType.INITIAL); + // + // /** + // * | | + // * |-- A --| |-- B --|-- C --| + // * | | + // * |-- X --| + // * | | + // * |-- Y --| + // * | | + // * |-- Z --| + // * | | + // */ + // ret.continues_with(B).continues_with(C); + // + + }); test(".None.#.equivalent(.None.#)", () => { const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. const B = Ray.None().o({ js: 'B' }).as_reference(); @@ -490,19 +508,19 @@ describe("Ray", () => { expect(ret.self.terminal.self.self.any.js).toBe('A'); expect(ret.self.terminal.self.self.self.any.js).toBe('B'); }); - test("(A:vertex.# = B:vertex.# = C:vertex.#)", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - // const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - - A.equivalent2(B); - // C.equivalent2(D); - - // A.equivalent2(D); - A.equivalent2(C); - - }); + // test("(A:vertex.# = B:vertex.# = C:vertex.#)", () => { + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + // // const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); + // + // A.equivalent2(B); + // // C.equivalent2(D); + // + // // A.equivalent2(D); + // A.equivalent2(C); + // + // }); test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 51c21a1..7ccb402 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -180,8 +180,14 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_initial = (): Ray => { const [terminal_vertex, initial_vertex] = this.___as_vertices(); + initial_vertex.o({ js: 'initial_vertex' }) + .self.terminal.as_reference() + .equivalent2( + terminal_vertex.o({ js: 'terminal_vertex' }) + .self.initial.as_reference() + ) + // TODO BETTER DEBUG - initial_vertex.o({ js: 'initial_vertex' }).continues_with(terminal_vertex.o({ js: 'terminal_vertex' })) return initial_vertex.self.initial.as_reference(); } @@ -194,10 +200,16 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_terminal = (): Ray => { const [initial_vertex, terminal_vertex] = this.___as_vertices(); - return ( - initial_vertex.o({ js: 'initial_vertex' }).continues_with(terminal_vertex.o({ js: 'terminal_vertex' })) // TODO BETTER DEBUG + initial_vertex.o({ js: 'initial_vertex' }) .self.terminal.as_reference() - ) + .equivalent2( + terminal_vertex.o({ js: 'terminal_vertex' }) + .self.initial.as_reference() + ) + + // TODO BETTER DEBUG + + return terminal_vertex.self.terminal.as_reference(); } private ___as_vertices = (): [Ray, Ray] => { if (!Ray.is_orbit(this.self, this.self.self.self)) From 70e02f025a2019dc36366052e2cad40c51a72a41 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 16:48:15 +0100 Subject: [PATCH 092/138] 2024/01/17 - Helper method for stepping to direction: 'follow' ; this will probably be renamed to `.step` ? --- src/@orbitmines/explorer/Ray.spec.ts | 64 +++++++++---------- src/@orbitmines/explorer/Ray.ts | 34 ++++++---- .../explorer/debug/DebugCanvas.tsx | 4 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 4 +- 4 files changed, 58 insertions(+), 48 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 8e372e9..f631aff 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -350,7 +350,7 @@ describe("Ray", () => { // A.continues_with(B).continues_with(C); // X.continues_with(Y).continues_with(Z); // - // A.self.terminal.as_reference().equivalent2(Y.self.initial.as_reference()); + // A.follow().equivalent2(Y.follow(Ray.directions.previous)); // // expect(Y.previous()).toBe('?') // }); @@ -376,7 +376,7 @@ describe("Ray", () => { // // X.continues_with(Y).continues_with(Z); - // const ret = A.continues_with(X.self.initial.as_reference()); + // const ret = A.continues_with(X.follow(Ray.directions.previous)); @@ -392,14 +392,14 @@ describe("Ray", () => { // * | \ // */ // expect(ret.type).toBe(RayType.INITIAL); - // expect(ret.self.terminal.as_reference().is_none()).toBe(false); - // expect([...ret.self.terminal.as_reference()].map( + // expect(ret.follow().is_none()).toBe(false); + // expect([...ret.follow()].map( // return_ref => return_ref.type // )).toEqual([RayType.VERTEX, RayType.VERTEX, RayType.VERTEX]); - // expect([...ret.self.terminal.as_reference()].map( + // expect([...ret.follow()].map( // return_ref => return_ref.self.type // )).toEqual([RayType.TERMINAL, RayType.TERMINAL, RayType.TERMINAL]); - // expect([...ret.self.terminal.as_reference()].map( + // expect([...ret.follow()].map( // return_ref => { // const return_vertex = return_ref.self; // const terminal = return_vertex.self; @@ -408,7 +408,7 @@ describe("Ray", () => { // return continued_vertex.any.js; // } // )).toEqual(['X', 'Y', 'Z']); - // expect([...ret.self.terminal.as_reference()].map( + // expect([...ret.follow()].map( // return_ref => { // const vertex = return_ref.self; // const terminal = vertex.self; @@ -531,7 +531,7 @@ describe("Ray", () => { expect(terminal.type).toBe(RayType.TERMINAL); - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); /** * terminal_vertex = A @@ -539,16 +539,16 @@ describe("Ray", () => { * * Since we're at the terminal, and reversing direction, that gives 'terminal_vertex' first, then 'initial_vertex'. */ - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); /** * These should keep looping... * TODO: Better test helper for this */ - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); }); test("(A:vertex.# = B:vertex.#) ; B.as_terminal", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -560,18 +560,18 @@ describe("Ray", () => { expect(terminal.type).toBe(RayType.TERMINAL); - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); /** * These should keep looping... * TODO: Better test helper for this */ - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...terminal.self.initial.as_reference().traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); }); test("(A:vertex.# = B:vertex.#) ; A.as_initial", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -583,18 +583,18 @@ describe("Ray", () => { expect(initial.type).toBe(RayType.INITIAL); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); /** * These should keep looping... * TODO: Better test helper for this */ - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); }); test("(A:vertex.# = B:vertex.#) ; B.as_initial", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -606,18 +606,18 @@ describe("Ray", () => { expect(initial.type).toBe(RayType.INITIAL); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); /** * These should keep looping... * TODO: Better test helper for this */ - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...initial.self.terminal.as_reference().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); }); test(".None.#.equivalent(.vertex.#)", () => { const A = Ray.None().as_reference(); @@ -782,7 +782,7 @@ describe("Ray", () => { expect(vertex.self).toBe(vertex.self.initial.terminal); expect(vertex.self).toBe(vertex.self.terminal.initial); - expect(vertex.self).toBe(vertex.self.initial.as_reference().self.terminal); + expect(vertex.self).toBe(vertex.follow(Ray.directions.previous).self.terminal); }); test(".vertex.initial.#", () => { /** [--|--] */ const vertex = Ray.vertex(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 7ccb402..d14ae65 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -181,15 +181,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? const [terminal_vertex, initial_vertex] = this.___as_vertices(); initial_vertex.o({ js: 'initial_vertex' }) - .self.terminal.as_reference() + .follow() .equivalent2( terminal_vertex.o({ js: 'terminal_vertex' }) - .self.initial.as_reference() + .follow(Ray.directions.previous) ) // TODO BETTER DEBUG - return initial_vertex.self.initial.as_reference(); + return initial_vertex.follow(Ray.directions.previous); } /** * Moves `this.self` and `this.self.self` to a new line. @@ -201,15 +201,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? const [initial_vertex, terminal_vertex] = this.___as_vertices(); initial_vertex.o({ js: 'initial_vertex' }) - .self.terminal.as_reference() + .follow() .equivalent2( terminal_vertex.o({ js: 'terminal_vertex' }) - .self.initial.as_reference() + .follow(Ray.directions.previous) ) // TODO BETTER DEBUG - return terminal_vertex.self.terminal.as_reference(); + return terminal_vertex.follow(); } private ___as_vertices = (): [Ray, Ray] => { if (!Ray.is_orbit(this.self, this.self.self.self)) @@ -483,7 +483,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } - // throw new PreventsImplementationBug(`[${initial.self.initial.any.js}]-[${initial.self.initial.as_reference().next.self.any.js}]/[${terminal.self.terminal.any.js}]`) + // throw new PreventsImplementationBug(`[${initial.self.initial.any.js}]-[${initial.follow(Ray.directions.previous).next.self.any.js}]/[${terminal.self.terminal.any.js}]`) // TODO initial.self.as_vertex().continues_with(terminal.self.as_vertex()) @@ -521,7 +521,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return terminal.___primitive_switch({ [RayType.VERTEX]: () => { - initial.self.terminal.as_reference().equivalent(terminal.self.initial.as_reference()); + initial.follow().equivalent(terminal.follow(Ray.directions.previous)); return terminal; }, [RayType.INITIAL]: () => { @@ -530,11 +530,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO; This is probably incredibly hacky now - const terminals = [...terminal.self.terminal.as_reference()].map(vertex => vertex.___primitive_switch({ + const terminals = [...terminal.follow()].map(vertex => vertex.___primitive_switch({ [RayType.VERTEX]: (ref) => { // TODO: Currently takes the vertex, drops the initial/terminal sides and reassigns them to this structure - initial.self.terminal.as_reference().equivalent(ref.self.initial.as_reference()); + initial.follow().equivalent(ref.follow(Ray.directions.previous)); ref.self.terminal = ref.self.___empty_terminal(); return ref.self.terminal; @@ -558,7 +558,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO; Now a Ray/list of [--| ] (terminal) connections. - return ret.self.initial.as_reference(); // Ret the intial ref of this list TODO + return ret.follow(Ray.directions.previous); // Ret the intial ref of this list TODO }, }); } @@ -573,7 +573,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? pop = (): Ray => this.___primitive_switch({ [RayType.VERTEX]: () => { - const previous_vertex = this.self.initial.self.initial.as_reference(); + const previous_vertex = this.self.initial.follow(Ray.directions.previous); if (this.is_none()) { return this; // TODO; Already empty, perhaps throw @@ -660,6 +660,16 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? previous: (ref: Ray) => ref.self.initial.as_reference(), } + // TODO: Nicer one? ; Differentiate between ".next" and just "follow the pointer" ? + follow = (step: Implementation = Ray.directions.next): Ray => { + // let pointer = new Ray({ + // initial: () => this, + // terminal: () => step(this), + // }); TODO USE POINTER? + + return step(this); + } + /** * .next */ diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index a6f4838..bb3578f 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -14,9 +14,9 @@ import _ from "lodash"; // TODO: Could be a function on Ray (any func really) export const Render = ({ ray, Interface }: { ray: Ray, Interface: Ray }) => { - const initial: Required = ray.self.initial.as_reference().render_options(Interface); + const initial: Required = ray.follow(Ray.directions.previous).render_options(Interface); const vertex: Required = ray.render_options(Interface); - const terminal: Required = ray.self.terminal.as_reference().render_options(Interface); + const terminal: Required = ray.follow().render_options(Interface); switch (ray.type) { case RayType.REFERENCE: diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 3a40a91..432cc83 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -148,11 +148,11 @@ export const Render2 = ({ ray, Interface, show = { initial: true, terminal: tru const index = ___index(ray); let added = [15 * index, 60 * index, 0]; - const initial: Required = ray.self.initial.as_reference().render_options(Interface); + const initial: Required = ray.follow(Ray.directions.previous).render_options(Interface); initial.position = add_(initial.position, added); const vertex: Required = ray.render_options(Interface); vertex.position = add_(vertex.position, added); - const terminal: Required = ray.self.terminal.as_reference().render_options(Interface); + const terminal: Required = ray.follow().render_options(Interface); terminal.position = add_(terminal.position, added); switch (ray.type) { From 96769c02d05d977edfabd32946f1078293690b13 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 17:09:55 +0100 Subject: [PATCH 093/138] 2024/01/17 - Replace older `continues_with` with `compose`, and `equivalence2` with new `equivalence.` --- src/@orbitmines/explorer/Ray.spec.ts | 60 +++--- src/@orbitmines/explorer/Ray.ts | 212 ++++++------------- src/@orbitmines/external/chyp/Chyp.ts | 4 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 8 +- 4 files changed, 96 insertions(+), 188 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index f631aff..cf5895f 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -25,7 +25,7 @@ describe("Ray", () => { const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - A.continues_with(B).continues_with(C); + A.compose(B).compose(C); expect(() => A.copy()).toThrow(); // const copy = A.copy(); @@ -37,7 +37,7 @@ describe("Ray", () => { const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - A.continues_with(B).continues_with(C); + A.compose(B).compose(C); // let pointer = A.step(Ray.directions.next()(A)); @@ -135,7 +135,7 @@ describe("Ray", () => { const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - A.continues_with(B).continues_with(C); + A.compose(B).compose(C); // let pointer = A.step(Ray.directions.next()(A)); @@ -192,7 +192,7 @@ describe("Ray", () => { const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); - A.continues_with(B).continues_with(C); + A.compose(B).compose(C); expect(A.has_next()).toBe(true); expect(A.has_next(Ray.directions.next)).toBe(true); @@ -220,7 +220,7 @@ describe("Ray", () => { const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); - A.continues_with(B).continues_with(C); + A.compose(B).compose(C); expect(A.first().self.any.js).toBe('A'); expect(B.first().self.any.js).toBe('A'); @@ -235,7 +235,7 @@ describe("Ray", () => { const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); - A.continues_with(B).continues_with(C); + A.compose(B).compose(C); expect(A.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); expect(A.at(-100).is_none()).toBe(true); @@ -318,7 +318,7 @@ describe("Ray", () => { expect(A.next().is_none()).toBe(true); expect(A.previous().is_none()).toBe(true); - A.continues_with(B).continues_with(C); + A.compose(B).compose(C); expect(A.next().is_none()).toBe(false); expect(A.previous().is_none()).toBe(true); @@ -347,10 +347,10 @@ describe("Ray", () => { // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); // - // A.continues_with(B).continues_with(C); - // X.continues_with(Y).continues_with(Z); + // A.compose(B).compose(C); + // X.compose(Y).compose(Z); // - // A.follow().equivalent2(Y.follow(Ray.directions.previous)); + // A.follow().equivalent(Y.follow(Ray.directions.previous)); // // expect(Y.previous()).toBe('?') // }); @@ -374,9 +374,9 @@ describe("Ray", () => { // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); // - // X.continues_with(Y).continues_with(Z); + // X.compose(Y).compose(Z); - // const ret = A.continues_with(X.follow(Ray.directions.previous)); + // const ret = A.compose(X.follow(Ray.directions.previous)); @@ -430,7 +430,7 @@ describe("Ray", () => { // * |-- Z --| // * | | // */ - // ret.continues_with(B).continues_with(C); + // ret.compose(B).compose(C); // }); @@ -451,7 +451,7 @@ describe("Ray", () => { expect(B.self.self.any.js).toBe('B'); expect(B.self.self.self.any.js).toBe('B'); - A.equivalent2(B); + A.equivalent(B); expect(A.type).toBe(RayType.REFERENCE); // Turns A into a reference to B. expect(B.type).toBe(RayType.REFERENCE); // Turns B into a reference to A. @@ -481,7 +481,7 @@ describe("Ray", () => { expect(B.is_none()).toBe(false); expect(B.dereference.is_none()).toBe(true); - let ret = A.equivalent2(B); + let ret = A.equivalent(B); expect(A.type).toBe(RayType.VERTEX); expect(B.type).toBe(RayType.VERTEX); @@ -514,18 +514,18 @@ describe("Ray", () => { // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); // // const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); // - // A.equivalent2(B); - // // C.equivalent2(D); + // A.equivalent(B); + // // C.equivalent(D); // - // // A.equivalent2(D); - // A.equivalent2(C); + // // A.equivalent(D); + // A.equivalent(C); // // }); test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - A.equivalent2(B); + A.equivalent(B); const terminal = A.as_terminal(); @@ -554,7 +554,7 @@ describe("Ray", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - A.equivalent2(B); + A.equivalent(B); const terminal = B.as_terminal(); @@ -577,7 +577,7 @@ describe("Ray", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - A.equivalent2(B); + A.equivalent(B); const initial = A.as_initial(); @@ -600,7 +600,7 @@ describe("Ray", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - A.equivalent2(B); + A.equivalent(B); const initial = B.as_initial(); @@ -632,7 +632,7 @@ describe("Ray", () => { const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - A.continues_with(B).continues_with(C); + A.compose(B).compose(C); expect(A.as_array().map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); // TODO: This may or may not be expected behavior, you could make a case for saying it should render both sides for .as_array. ??? @@ -667,7 +667,7 @@ describe("Ray", () => { let A = Ray.vertex().o({ js: 'A' }).as_reference(); let B = Ray.vertex().o({ js: 'B'}).as_reference(); - A.continues_with(B); + A.compose(B); B = A.next(); @@ -683,11 +683,11 @@ describe("Ray", () => { .any.js ).toBe('B'); }); - test(".vertex.#.continues_with(.vertex.#)", () => { + test(".vertex.#.compose(.vertex.#)", () => { let A = Ray.vertex().o({ js: 'A' }).as_reference(); let B = Ray.vertex().o({ js: 'B'}).as_reference(); - B = A.continues_with(B); + B = A.compose(B); expect(B.type).toBe(RayType.VERTEX); expect(B.self.any.js).toBe('B'); @@ -701,14 +701,14 @@ describe("Ray", () => { .any.js ).toBe('B'); }); - test("[.vertex.#, .vertex.#].#.continues_with", () => { + test("[.vertex.#, .vertex.#].#.compose", () => { let A = Ray.vertex().o({ js: 'A' }).as_reference(); let B = Ray.vertex().o({ js: 'B' }).as_reference(); B = new Ray({ initial: A.as_arbitrary(), terminal: B.as_arbitrary() - }).as_reference().continues_with(); + }).as_reference().compose(); expect(B.type).toBe(RayType.VERTEX); expect(B.self.any.js).toBe('B'); @@ -725,7 +725,7 @@ describe("Ray", () => { // test(".vertex.#.debug", () => { // const a = Ray.vertex().as_reference(); // const b = Ray.vertex().as_reference(); - // a.continues_with(b); + // a.compose(b); // // const debug = {}; // a.debug(debug); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index d14ae65..47c8a83 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,4 +1,4 @@ -import _, {initial} from "lodash"; +import _ from "lodash"; import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; @@ -168,7 +168,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO: Disregards anything on this.self.self?? - or not with current?? - return vertex.as_reference();//.continues_with(current.as_reference()); + return vertex.as_reference();//.compose(current.as_reference()); } /** @@ -180,12 +180,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_initial = (): Ray => { const [terminal_vertex, initial_vertex] = this.___as_vertices(); - initial_vertex.o({ js: 'initial_vertex' }) - .follow() - .equivalent2( - terminal_vertex.o({ js: 'terminal_vertex' }) - .follow(Ray.directions.previous) - ) + initial_vertex.o({ js: 'initial_vertex' }).compose(terminal_vertex.o({ js: 'terminal_vertex' })) + + // TODO: Without compose; + // initial_vertex.o({ js: 'initial_vertex' }) + // .follow() + // .equivalent( + // terminal_vertex.o({ js: 'terminal_vertex' }) + // .follow(Ray.directions.previous) + // ) // TODO BETTER DEBUG @@ -200,12 +203,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_terminal = (): Ray => { const [initial_vertex, terminal_vertex] = this.___as_vertices(); - initial_vertex.o({ js: 'initial_vertex' }) - .follow() - .equivalent2( - terminal_vertex.o({ js: 'terminal_vertex' }) - .follow(Ray.directions.previous) - ) + initial_vertex.o({ js: 'initial_vertex' }).compose(terminal_vertex.o({ js: 'terminal_vertex' })) + + // TODO: Without compose; + // initial_vertex.o({ js: 'initial_vertex' }) + // .follow() + // .equivalent( + // terminal_vertex.o({ js: 'terminal_vertex' }) + // .follow(Ray.directions.previous) + // ) // TODO BETTER DEBUG @@ -230,10 +236,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** [ ] */ static None = () => new Ray({ }).o({ }); /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { - // /** [?????] -> [ ???] */ as_initial = () => new Ray({ vertex: () => this.initial, terminal: this.as_arbitrary(), js: () => 'initial ref' }); - // /** [?????] -> [??? ] */ as_terminal = () => - // new Ray({ initial: this.as_arbitrary(), vertex: () => this.terminal, js: () => 'terminal ref' }); // TODO: These fields as DEBUG - /** [ ] */ const vertex = Ray.None(); /** [-- ] */ vertex.initial = vertex.___empty_initial(); /** [ ? ] */ vertex.vertex = value; @@ -244,7 +246,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** [ |-?] */ static initial = () => Ray.vertex().initial; /** [?-| ] */ static terminal = () => Ray.vertex().terminal; - // TODO; Temp placeholders for now + // TODO; Temp placeholders for now - & BETTER DEBUG ___empty_initial = () => new Ray({ vertex: Ray.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); ___empty_terminal = () => new Ray({ vertex: Ray.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); @@ -360,6 +362,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } step= Ray.___func(Ray.step).as_method(this); + // TODO; Maybe replace switch with 'zip'?, What are the practical differences? protected ___primitive_switch = (cases: SwitchCases): Ray => { const _case = cases[this.type]; @@ -369,6 +372,27 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return _case(this); } + /** + * TODO : COMPOSE EMPTY AS FIRST ELEMENT: + * if (initial.is_none()) { + * // 'Empty' vertex from this perspective. + * + * initial.vertex = terminal.as_arbitrary(); + * console.log('first element'); + * return terminal; + * } + */ + + // TODO: Test if references hold after equivalence/composition... + + + // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? + // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? + + // TODO: Should do, one timesteap ahead, collapse one reference, and then recursively call continues_with on the vlaue at the reference, until it yields something. + + // TODO AS += through property + // TODO: Generally, return something which knows where all continuations are. // @alias('merge, 'continues_with', 'compose') /** * Compose as "Equivalence at Continuations": (can usually be done in parallel - not generally) @@ -381,7 +405,16 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * @see "Continuations as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence */ static compose = Ray.___func(ref => { + let { initial, terminal} = ref.self; + + if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) { + throw new PreventsImplementationBug(`[${initial.type}] - [${terminal.type}] - only composing vertices for now`); + } + + initial.follow().equivalent(terminal.follow(Ray.directions.previous)); + // return ref; TODO + return terminal; }); compose = Ray.compose.as_method(this); @@ -395,7 +428,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies */ - static equivalent2 = Ray.___func(ref => { + static equivalent = Ray.___func(ref => { let { initial, terminal} = ref.self; /** @@ -435,136 +468,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * - Then we're left with the 'beginning' of one iterator, and the 'end' of the other. And the only thing that's left to do, is draw a simple (ignorant) equivalence between the two. (Basically call this function again, and call {ignorant_equivalence}). * TODO: This could also be a line with some debug information. */ - initial.as_initial().equivalent2(terminal.as_terminal()); - - return ref; - }); - equivalent2 = Ray.equivalent2.as_method(this); - - static equivalent= Ray.___func(ref => { - let { initial, terminal } = ref.self; - - // TODO: Can just move the terminal which holds the oointer to the boundary - - // TODO: IS THIS EVEN HOW THIS SHOULD WORK?? - Now just takes the pointer and assumes that as its own - - // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? - // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? - - if (initial.self.self.is_none() && terminal.self.self.is_none()) { - // throw new NotImplementedError('a'); - /** - * i.e. initial.self.self.self === initial.self.self.self.self && terminal.self.self.self === terminal.self.self.self.self - * Or in other words: There's no connection currently defined on {initial.self} & {terminal.self}. - * - * Since that's the case, they can just reference each-other directly - Making a slightly larger orbit. - */ - initial.self.self = terminal.self.as_arbitrary(); - terminal.self.self = initial.self.as_arbitrary(); - return ref; - } - - if (initial.self.self.is_none() || terminal.self.self.is_none()) { - throw new PreventsImplementationBug('What is the case in which one side is ignorant and the other is not?'); - } - - /** - * If there currently exist structure on (initial/terminal).self.self (i.e. existing connections), we need to add to them. - */ - - // TODO: COULD ADD?? - probably the case for all these equivalences. - // TODO: Should do, one timesteap ahead, collapse one reference, and then recursively call continues_with on the vlaue at the reference, until it yields something. - - - if (!(Ray.is_orbit(initial.self, initial.self.self.self) && Ray.is_orbit(terminal.self, terminal.self.self.self))) { - // throw new PreventsImplementationBug('Just add?'); - initial.self.continues_with(terminal.self); - return ref; - } - - - // throw new PreventsImplementationBug(`[${initial.self.initial.any.js}]-[${initial.follow(Ray.directions.previous).next.self.any.js}]/[${terminal.self.terminal.any.js}]`) - - // TODO - initial.self.as_vertex().continues_with(terminal.self.as_vertex()) + initial.as_initial().equivalent(terminal.as_terminal()); return ref; }); equivalent = Ray.equivalent.as_method(this); - // protected equivalent = (b: Ray) => { // TODO: Generic, now just ignorantly sets the vertices to eachother - - // TODO AS += through property - static continues_with = Ray.___func(ref => { - const { initial, terminal } = ref.self; - - // TODO; Maybe replace switch with 'zip'?, What are the practical differences? - return initial.___primitive_switch({ - [RayType.REFERENCE]: - "We could either go inside the reference and continue there, or expand the direction of reference." + - "We could move when a reference is on the vertex, set the type to vertex from the perspective of the reference", - [RayType.TERMINAL]: "", - // [RayType.INITIAL]: () => { - // - // }, - - // "Could be each element found in this direction, or continue *after* the entire direction", ; TODO: This continue is probably more appropraite for vertex, then move to the last one, and compose there... - [RayType.VERTEX]: (): Ray => { - // const next_vertex = b; // TODO: Could be a reference too, now just force as a next element - - if (initial.is_none()) { - // 'Empty' vertex from this perspective. - - initial.vertex = terminal.as_arbitrary(); - console.log('first element'); - return terminal; // TODO: Generally, return something which knows where all continuations are. - } - - return terminal.___primitive_switch({ - [RayType.VERTEX]: () => { - initial.follow().equivalent(terminal.follow(Ray.directions.previous)); - return terminal; - }, - [RayType.INITIAL]: () => { - // TODO: You could make a case of preserving the structure of this, or even superposing it on the continuations we're defining here, ... might need a better handle on this at some point - // TODO: Could even have a difference of destroying the connecting itself vs not.. - - // TODO; This is probably incredibly hacky now - - const terminals = [...terminal.follow()].map(vertex => vertex.___primitive_switch({ - [RayType.VERTEX]: (ref) => { - - // TODO: Currently takes the vertex, drops the initial/terminal sides and reassigns them to this structure - initial.follow().equivalent(ref.follow(Ray.directions.previous)); - ref.self.terminal = ref.self.___empty_terminal(); - - return ref.self.terminal; - } - })); - - let ret: Ray | undefined; - let current: Ray; - terminals.forEach(terminal => { - const next = Ray.vertex(terminal.as_arbitrary()).as_reference(); - - if (ret === undefined) { - ret = current = next; - } else { - current = current.continues_with(next); - } - }); - - if (ret === undefined) - throw new PreventsImplementationBug(); - - // TODO; Now a Ray/list of [--| ] (terminal) connections. - - return ret.follow(Ray.directions.previous); // Ret the intial ref of this list TODO - }, - }); - } - }); - }); - continues_with = Ray.continues_with.as_method(this); // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... @@ -779,7 +687,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (!ret) { current = ret = vertex; } else { - current = current?.continues_with(vertex); + current = current?.compose(vertex); } } @@ -792,7 +700,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return Ray.size(of, value).at(index); } /** - * Just uses length/size for permutation. TODO: More complex permutation implementation should follow at some point. (@see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=One%20of%20them%20could%20even%20be%20putting%20both%20our%20points%20on%20our%20selection for an example) + * Just uses length/size for permutation. TODO: More complex permutation/enumeration implementation should follow at some point. (@see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=One%20of%20them%20could%20even%20be%20putting%20both%20our%20points%20on%20our%20selection for an example) * * @see "Combinatorics as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Combinatorics%20%2D%20Combinatorics%20as%20Equivalence */ @@ -1067,7 +975,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; } - // TODO: These are just (.back/.front) + .continues_with ?? + // TODO: These are just (.back/.front) + .compose ?? push_back = (ray: Ray) => { throw new NotImplementedError(); } push_front = (ray: Ray) => { throw new NotImplementedError(); } @@ -1250,7 +1158,7 @@ export namespace JS { // |-false->-true-| (could of course also be reversed) const _false = Ray.vertex().o({ js: false }); const _true = Ray.vertex().o({ js: true }); - _false.continues_with(_true); + _false.compose(_true); return (boolean ? _true : _false).as_reference(); } @@ -1273,7 +1181,7 @@ export namespace JS { const terminal = new Ray({ initial: () => initial }); - // initial.continues_with(() => terminal.as_reference()); + // initial.compose(() => terminal.as_reference()); // if (initial.is_some()) // initial.terminal = () => terminal; // TODO REPEAT FROM BELOW @@ -1288,7 +1196,7 @@ export namespace JS { terminal: () => next(current) }).o({js: iterator_result.value}); - // initial.continues_with(() => current.as_reference()); + // initial.compose(() => current.as_reference()); if (initial.is_some()) initial.terminal = () => current; diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index f22aa92..2a59472 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -100,11 +100,11 @@ export namespace Chyp { // Graph.inputs = Ray.initial get inputs(): Ray { return this.initial; } set inputs(ray: Arbitrary) { this.initial = ray; } set_inputs = (ray: Arbitrary): Graph => { this.inputs = ray; return this; } - add_inputs = (ray: Ray): Graph => { this.inputs.continues_with(ray); return this; } + add_inputs = (ray: Ray): Graph => { this.inputs.compose(ray); return this; } // Graph.inputs = Ray.terminal get outputs(): Ray { return this.terminal; } set outputs(ray: Arbitrary) { this.terminal = ray; } set_outputs = (ray: Arbitrary): Graph => { this.outputs = ray; return this; } - add_outputs = (ray: Ray): Graph => { this.outputs.continues_with(ray); return this; } + add_outputs = (ray: Ray): Graph => { this.outputs.compose(ray); return this; } } diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 432cc83..fa9b29f 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -279,7 +279,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { position: add(selection.any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) }); - Interface.any.selection = selection.continues_with(next); + Interface.any.selection = selection.compose(next); Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { ray.any.traversed = true; return ray.as_reference(); @@ -337,7 +337,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { // selection.o({...selection.o, position: add(selection.any.position ?? [0, 0, 0], [0, i * 2, 0])}) - // selection.continues_with( + // selection.compose( // ); } @@ -490,7 +490,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { position: add(selection.any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) }); - Interface.any.selection = selection.continues_with(next); + Interface.any.selection = selection.compose(next); Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { ray.any.traversed = true; return ray.as_reference(); @@ -548,7 +548,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { // selection.o({...selection.o, position: add(selection.any.position ?? [0, 0, 0], [0, i * 2, 0])}) - // selection.continues_with( + // selection.compose( // ); } From 06288fdcbe74340d0b850bc410150af4d84e7a09 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 17:18:53 +0100 Subject: [PATCH 094/138] 2024/01/17 - Replace older `continues_with` with `compose`, and `equivalence2` with new `equivalence.` --- src/@orbitmines/explorer/Ray.spec.ts | 2 +- src/@orbitmines/explorer/Ray.ts | 20 ++------------------ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index cf5895f..1928113 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -375,7 +375,7 @@ describe("Ray", () => { // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); // // X.compose(Y).compose(Z); - + // // const ret = A.compose(X.follow(Ray.directions.previous)); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 47c8a83..6e45e6f 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -180,15 +180,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_initial = (): Ray => { const [terminal_vertex, initial_vertex] = this.___as_vertices(); - initial_vertex.o({ js: 'initial_vertex' }).compose(terminal_vertex.o({ js: 'terminal_vertex' })) - - // TODO: Without compose; - // initial_vertex.o({ js: 'initial_vertex' }) - // .follow() - // .equivalent( - // terminal_vertex.o({ js: 'terminal_vertex' }) - // .follow(Ray.directions.previous) - // ) + initial_vertex.o({ js: 'initial_vertex' }).compose(terminal_vertex.o({ js: 'terminal_vertex' })); // TODO BETTER DEBUG @@ -203,15 +195,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_terminal = (): Ray => { const [initial_vertex, terminal_vertex] = this.___as_vertices(); - initial_vertex.o({ js: 'initial_vertex' }).compose(terminal_vertex.o({ js: 'terminal_vertex' })) - - // TODO: Without compose; - // initial_vertex.o({ js: 'initial_vertex' }) - // .follow() - // .equivalent( - // terminal_vertex.o({ js: 'terminal_vertex' }) - // .follow(Ray.directions.previous) - // ) + initial_vertex.o({ js: 'initial_vertex' }).compose(terminal_vertex.o({ js: 'terminal_vertex' })); // TODO BETTER DEBUG From 2a637c899a310da4dd09c966e26262519c960a4a Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 17:55:34 +0100 Subject: [PATCH 095/138] 2024/01/17 - Composing lists --- src/@orbitmines/explorer/Ray.spec.ts | 35 +++++++++++++++------------- src/@orbitmines/explorer/Ray.ts | 18 ++------------ 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 1928113..6536bd4 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -338,22 +338,25 @@ describe("Ray", () => { expect(A.next().previous().next().next().previous().self.any.js).toBe('B'); expect(A.next().previous().next().next().previous().next().self.any.js).toBe('C'); }); - // test("[A, B, C], [X, Y, Z] ; A.terminal = Y.initial", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - // - // const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); - // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); - // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); - // - // A.compose(B).compose(C); - // X.compose(Y).compose(Z); - // - // A.follow().equivalent(Y.follow(Ray.directions.previous)); - // - // expect(Y.previous()).toBe('?') - // }); + test("[A, B, C], [X, Y, Z] ; C.compose(X)", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); + const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); + const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); + + A.compose(B).compose(C); + X.compose(Y).compose(Z); + + C.compose(X); + + expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); + expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); + expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X', 'C', 'B', 'A']); + expect([...X].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + }); test("[A, [X, Y, Z].initial, B, C][.next(), .previous()]", () => { // /** // * | | diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 6e45e6f..d71f638 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -157,20 +157,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ get dereference() { return this.self.self.as_reference(); } - /** - * Places the current structure inside a new non-ignorant vertex. - */ - as_vertex = (): Ray => { - const vertex = Ray.vertex(this.self.as_arbitrary()); - const current = this.self.self; - - this.self.self = vertex.as_arbitrary(); - - // TODO: Disregards anything on this.self.self?? - or not with current?? - - return vertex.as_reference();//.compose(current.as_reference()); - } - /** * Moves `this.self` and `this.self.self` to a new line. * @@ -206,9 +192,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? throw new PreventsImplementationBug('Is there a use-case for this? Probably not?'); //TODO // TODO NOTE: THE ORDER OF `this.self` first matters here. - return [this.self.___as_vertex2(), this.___as_vertex2()]; + return [this.self.___as_vertex(), this.___as_vertex()]; } - private ___as_vertex2 = (): Ray => { + private ___as_vertex = (): Ray => { return this.self.___ignorantly_equivalent(Ray.vertex().as_reference()); } private ___ignorantly_equivalent = (ref: Ray): Ray => { From 7cfcdf660a92919b5c4be5b3f4a5e965c9ea5b90 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 20:19:38 +0100 Subject: [PATCH 096/138] 2024/01/17 - Finalizing '.equivalent' + tests ; just one more bug somewhere --- src/@orbitmines/explorer/Ray.spec.ts | 234 ++++++++++++++++++++------- src/@orbitmines/explorer/Ray.ts | 58 +++++-- 2 files changed, 225 insertions(+), 67 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 6536bd4..00870d5 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -357,6 +357,38 @@ describe("Ray", () => { expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X', 'C', 'B', 'A']); expect([...X].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); }); + // test("(A:vertex.# = B:vertex.# = C:vertex.#)", () => { + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + // // const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); + // + // A.equivalent(B).equivalent(C); + // // C.equivalent(D); + // + // // A.equivalent(D); + // // A.equivalent(C); + // + // }); + // test("[A, B, C], [X, Y, Z] ; B.compose(X)", () => { + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + // + // const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); + // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); + // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); + // + // A.compose(B).compose(C); + // X.compose(Y).compose(Z); + // + // B.compose(X); + // + // // expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); + // // expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); + // // expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X', 'C', 'B', 'A']); + // // expect([...X].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + // }); test("[A, [X, Y, Z].initial, B, C][.next(), .previous()]", () => { // /** // * | | @@ -484,7 +516,7 @@ describe("Ray", () => { expect(B.is_none()).toBe(false); expect(B.dereference.is_none()).toBe(true); - let ret = A.equivalent(B); + A.equivalent(B); expect(A.type).toBe(RayType.VERTEX); expect(B.type).toBe(RayType.VERTEX); @@ -500,30 +532,130 @@ describe("Ray", () => { expect(B.self.any.js).toBe('B'); expect(B.self.self.any.js).toBe('A'); expect(B.self.self.self.any.js).toBe('B'); + }); + test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y).equiv(J).equiv(R)", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); + const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); + const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); - expect(ret.self.initial.any.js).toBe('A.#'); - expect(ret.self.initial.self.any.js).toBe('A'); - expect(ret.self.initial.self.self.any.js).toBe('B'); - expect(ret.self.initial.self.self.self.any.js).toBe('A'); + const I = Ray.vertex().o({ js: 'I' }).as_reference().o({ js: 'I.#' }); + const J = Ray.vertex().o({ js: 'J' }).as_reference().o({ js: 'J.#' }); + const K = Ray.vertex().o({ js: 'K' }).as_reference().o({ js: 'K.#' }); + + const Q = Ray.vertex().o({ js: 'Q' }).as_reference().o({ js: 'Q.#' }); + const R = Ray.vertex().o({ js: 'R' }).as_reference().o({ js: 'R.#' }); + const S = Ray.vertex().o({ js: 'S' }).as_reference().o({ js: 'S.#' }); + + A.compose(B).compose(C); + X.compose(Y).compose(Z); + I.compose(J).compose(K); + Q.compose(R).compose(S); + + // BEFORE .equivalent + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); + expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); + expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); + expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); + + expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); + expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); + expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); + expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); + expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); + + expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); + expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); + expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); + expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); + expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); + expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + + expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); + expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); + expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); + expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); + expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); + expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + + /** + * Drawing an equivalence between `B -> Y -> J -> R`. (Doesn't need to hold in some more abstract sense, it's just a line) + * | + * [--A--][--B--][--C--] + * | + * [--X--][--Y--][--Z--] + * | + * [--I--][--J--][--K--] + * | + * [--Q--][--R--][--S--] + * | + */ + B.equivalent(Y).equivalent(J) //.equivalent(R); TODO: Still one bug, J.# ->, makes the equiv(R) a parallel composition, so something is TERMINAL/INITIAL -> VERTEX + + // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); + expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); + expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); + expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); + + expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); + expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); + expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); + expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); + expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); + + expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); + expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); + expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); + expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); + expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); + expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + + expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); + expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); + expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); + expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); + expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); + expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + + // But they should be connected through their .vertex/.self: + expect(B.dereference.is_none()).toBe(false); + expect(B.dereference.type).toBe(RayType.VERTEX); + expect(B.dereference.self).not.toBe(B.self); + expect(B.dereference.self.self.any.js).toBe('B'); + expect(B.dereference.self.any.js).toBe('___as_vertex'); + expect([...B.dereference.traverse()].length).toBe(1); + expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(3); + expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J']); + + expect(Y.dereference.is_none()).toBe(false); + expect(Y.dereference.type).toBe(RayType.VERTEX); + expect(Y.dereference.self).not.toBe(Y.self); + expect(Y.dereference.self.self.any.js).toBe('Y'); + expect(Y.dereference.self.any.js).toBe('___as_vertex'); + expect([...Y.dereference.traverse()].length).toBe(2); + expect([...Y.dereference.traverse(Ray.directions.previous)].length).toBe(2); + expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J']); + + expect(J.dereference.is_none()).toBe(false); + expect(J.dereference.type).toBe(RayType.VERTEX); + expect(J.dereference.self).not.toBe(J.self); + expect(J.dereference.self.self.any.js).toBe('J'); + expect(J.dereference.self.any.js).toBe('___as_vertex'); + expect([...J.dereference.traverse()].length).toBe(3); + expect([...J.dereference.traverse(Ray.directions.previous)].length).toBe(1); - expect(ret.self.terminal.any.js).toBe('B.#'); - expect(ret.self.terminal.self.any.js).toBe('B'); - expect(ret.self.terminal.self.self.any.js).toBe('A'); - expect(ret.self.terminal.self.self.self.any.js).toBe('B'); }); - // test("(A:vertex.# = B:vertex.# = C:vertex.#)", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - // // const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - // - // A.equivalent(B); - // // C.equivalent(D); - // - // // A.equivalent(D); - // A.equivalent(C); - // - // }); test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); @@ -534,24 +666,17 @@ describe("Ray", () => { expect(terminal.type).toBe(RayType.TERMINAL); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); - - /** - * terminal_vertex = A - * initial_vertex = B - * - * Since we're at the terminal, and reversing direction, that gives 'terminal_vertex' first, then 'initial_vertex'. - */ - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); /** * These should keep looping... * TODO: Better test helper for this */ - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['A', 'B']); }); test("(A:vertex.# = B:vertex.#) ; B.as_terminal", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -563,18 +688,17 @@ describe("Ray", () => { expect(terminal.type).toBe(RayType.TERMINAL); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); /** * These should keep looping... * TODO: Better test helper for this */ - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['terminal_vertex', 'initial_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['B', 'A']); }); test("(A:vertex.# = B:vertex.#) ; A.as_initial", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -586,18 +710,17 @@ describe("Ray", () => { expect(initial.type).toBe(RayType.INITIAL); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); - - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); /** * These should keep looping... * TODO: Better test helper for this */ - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['A', 'B']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['A', 'B']); }); test("(A:vertex.# = B:vertex.#) ; B.as_initial", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -609,18 +732,17 @@ describe("Ray", () => { expect(initial.type).toBe(RayType.INITIAL); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); /** * These should keep looping... * TODO: Better test helper for this */ - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['initial_vertex', 'terminal_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['B', 'A']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['B', 'A']); }); test(".None.#.equivalent(.vertex.#)", () => { const A = Ray.None().as_reference(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index d71f638..ff16fe4 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -164,9 +164,19 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * ______ (<- initial pointer) */ as_initial = (): Ray => { + if (this.is_none() || this.dereference.is_none()) { + // TODO: Need some intuition for this check + return Ray.vertex(this.as_arbitrary()).as_reference().follow(Ray.directions.previous); + } + const [terminal_vertex, initial_vertex] = this.___as_vertices(); - initial_vertex.o({ js: 'initial_vertex' }).compose(terminal_vertex.o({ js: 'terminal_vertex' })); + if (initial_vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + if (terminal_vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + + initial_vertex.compose(terminal_vertex); // TODO BETTER DEBUG @@ -179,9 +189,19 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * _____ (<- terminal pointer) */ as_terminal = (): Ray => { + if (this.is_none() || this.dereference.is_none()) { + // TODO: Need some intuition for this check + return Ray.vertex(this.as_arbitrary()).as_reference().follow(); + } + const [initial_vertex, terminal_vertex] = this.___as_vertices(); - initial_vertex.o({ js: 'initial_vertex' }).compose(terminal_vertex.o({ js: 'terminal_vertex' })); + if (initial_vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + if (terminal_vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + + initial_vertex.compose(terminal_vertex); // TODO BETTER DEBUG @@ -195,11 +215,18 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return [this.self.___as_vertex(), this.___as_vertex()]; } private ___as_vertex = (): Ray => { - return this.self.___ignorantly_equivalent(Ray.vertex().as_reference()); + const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + + // this.self.self = vertex.self.as_arbitrary(); + // vertex.self.self = this.self.as_arbitrary(); + + // return this.___ignorantly_equivalent(Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' })); + + return this.___ignorantly_equivalent(vertex); } private ___ignorantly_equivalent = (ref: Ray): Ray => { - this.self = ref.as_arbitrary(); - ref.self = this.as_arbitrary(); + this.self.self = ref.self.as_arbitrary(); + ref.self.self = this.self.as_arbitrary(); return ref; } @@ -377,8 +404,12 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? static compose = Ray.___func(ref => { let { initial, terminal} = ref.self; + if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) + throw new PreventsImplementationBug(); + + // ${[...initial.self.initial.as_reference().traverse()].map(ref => ref.self.any.js)} if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) { - throw new PreventsImplementationBug(`[${initial.type}] - [${terminal.type}] - only composing vertices for now`); + throw new PreventsImplementationBug(`[${initial.type}] - [${terminal.type}] - only composing vertices for now (${initial.self.initial.any.js} -> ${terminal.self.terminal.any.js})`); } initial.follow().equivalent(terminal.follow(Ray.directions.previous)); @@ -411,8 +442,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. */ const ignorant_equivalence = (): Ray => { - initial.self.___ignorantly_equivalent(terminal.self); - return ref; + return initial.___ignorantly_equivalent(terminal); } // 2x Ray.None -> Turn into 2 empty references, referencing each-other. @@ -438,9 +468,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * - Then we're left with the 'beginning' of one iterator, and the 'end' of the other. And the only thing that's left to do, is draw a simple (ignorant) equivalence between the two. (Basically call this function again, and call {ignorant_equivalence}). * TODO: This could also be a line with some debug information. */ - initial.as_initial().equivalent(terminal.as_terminal()); + const a = initial.as_initial(); + const b = terminal.as_terminal(); - return ref; + if (a.type !== RayType.INITIAL) + throw new PreventsImplementationBug(); + if (b.type !== RayType.TERMINAL) + throw new PreventsImplementationBug(); + + return a.equivalent(b); }); equivalent = Ray.equivalent.as_method(this); @@ -560,7 +596,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? pointer = pointer.step().step(); if (pointer.terminal.type !== RayType.VERTEX) - throw new NotImplementedError(pointer.terminal.type); + throw new NotImplementedError(`${pointer.terminal.type} / ${pointer.terminal.self.self.any.js}`); return pointer.terminal; From 0a33dea182018fad34ffc63027d5b50ef34fce0f Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 20:27:59 +0100 Subject: [PATCH 097/138] 2024/01/17 - Separate chained .equivalent of 3 separate ones. Bug comes from empty at one side. --- src/@orbitmines/explorer/Ray.spec.ts | 153 +++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 9 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 00870d5..c9a67c1 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -555,6 +555,135 @@ describe("Ray", () => { I.compose(J).compose(K); Q.compose(R).compose(S); + // BEFORE .equivalent + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); + expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); + expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); + expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); + + expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); + expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); + expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); + expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); + expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); + + expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); + expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); + expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); + expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); + expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); + expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + + expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); + expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); + expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); + expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); + expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); + expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + + /** + * Drawing an equivalence between `B -> Y -> J -> R`. (Doesn't need to hold in some more abstract sense, it's just a line) + * | + * [--A--][--B--][--C--] + * | + * [--X--][--Y--][--Z--] + * | + * [--I--][--J--][--K--] + * | + * [--Q--][--R--][--S--] + * | + */ + B.equivalent(Y).equivalent(J)//;.equivalent(R); + + // TODO: Still one bug, J.# ->, makes the equiv(R) a parallel composition, so something is TERMINAL/INITIAL -> VERTEX + + // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); + expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); + expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); + expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); + + expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); + expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); + expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); + expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); + expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); + + expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); + expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); + expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); + expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); + expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); + expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + + expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); + expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); + expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); + expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); + expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); + expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + + // But they should be connected through their .vertex/.self: + expect(B.dereference.is_none()).toBe(false); + expect(B.dereference.type).toBe(RayType.VERTEX); + expect(B.dereference.self).not.toBe(B.self); + expect(B.dereference.self.self.any.js).toBe('B'); + expect(B.dereference.self.any.js).toBe('___as_vertex'); + expect([...B.dereference.traverse()].length).toBe(1); + expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); + + expect(Y.dereference.is_none()).toBe(false); + expect(Y.dereference.type).toBe(RayType.VERTEX); + expect(Y.dereference.self).not.toBe(Y.self); + expect(Y.dereference.self.self.any.js).toBe('Y'); + expect(Y.dereference.self.any.js).toBe('___as_vertex'); + expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); + + expect(J.dereference.is_none()).toBe(false); + expect(J.dereference.type).toBe(RayType.VERTEX); + expect(J.dereference.self).not.toBe(J.self); + expect(J.dereference.self.self.any.js).toBe('J'); + expect(J.dereference.self.any.js).toBe('___as_vertex'); + expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); + expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); + + expect(R.dereference.is_none()).toBe(false); + expect(R.dereference.type).toBe(RayType.VERTEX); + expect(R.dereference.self).not.toBe(R.self); + expect(R.dereference.self.self.any.js).toBe('R'); + expect(R.dereference.self.any.js).toBe('___as_vertex'); + expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); + expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R']); + }); + test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y) ; J.equiv(J) ; Y.equiv(J)", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); + const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); + const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); + + const I = Ray.vertex().o({ js: 'I' }).as_reference().o({ js: 'I.#' }); + const J = Ray.vertex().o({ js: 'J' }).as_reference().o({ js: 'J.#' }); + const K = Ray.vertex().o({ js: 'K' }).as_reference().o({ js: 'K.#' }); + + const Q = Ray.vertex().o({ js: 'Q' }).as_reference().o({ js: 'Q.#' }); + const R = Ray.vertex().o({ js: 'R' }).as_reference().o({ js: 'R.#' }); + const S = Ray.vertex().o({ js: 'S' }).as_reference().o({ js: 'S.#' }); + + A.compose(B).compose(C); + X.compose(Y).compose(Z); + I.compose(J).compose(K); + Q.compose(R).compose(S); + // BEFORE .equivalent expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); @@ -596,7 +725,9 @@ describe("Ray", () => { * [--Q--][--R--][--S--] * | */ - B.equivalent(Y).equivalent(J) //.equivalent(R); TODO: Still one bug, J.# ->, makes the equiv(R) a parallel composition, so something is TERMINAL/INITIAL -> VERTEX + B.equivalent(Y); + J.equivalent(R); + Y.equivalent(J); // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); @@ -634,27 +765,31 @@ describe("Ray", () => { expect(B.dereference.self.self.any.js).toBe('B'); expect(B.dereference.self.any.js).toBe('___as_vertex'); expect([...B.dereference.traverse()].length).toBe(1); - expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(3); - expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J']); + expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); expect(Y.dereference.is_none()).toBe(false); expect(Y.dereference.type).toBe(RayType.VERTEX); expect(Y.dereference.self).not.toBe(Y.self); expect(Y.dereference.self.self.any.js).toBe('Y'); expect(Y.dereference.self.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse()].length).toBe(2); - expect([...Y.dereference.traverse(Ray.directions.previous)].length).toBe(2); expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J']); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); expect(J.dereference.is_none()).toBe(false); expect(J.dereference.type).toBe(RayType.VERTEX); expect(J.dereference.self).not.toBe(J.self); expect(J.dereference.self.self.any.js).toBe('J'); expect(J.dereference.self.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse()].length).toBe(3); - expect([...J.dereference.traverse(Ray.directions.previous)].length).toBe(1); - + expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); + expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); + + expect(R.dereference.is_none()).toBe(false); + expect(R.dereference.type).toBe(RayType.VERTEX); + expect(R.dereference.self).not.toBe(R.self); + expect(R.dereference.self.self.any.js).toBe('R'); + expect(R.dereference.self.any.js).toBe('___as_vertex'); + expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); + expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R']); }); test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); From 5a7021bedeba6a27940741a82e73e07750bad9ab Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 20:29:16 +0100 Subject: [PATCH 098/138] 2024/01/17 - Separate chained .equivalent of 3 separate ones. Bug comes from empty at one side. --- src/@orbitmines/explorer/Ray.spec.ts | 171 ++++++++++++++------------- 1 file changed, 86 insertions(+), 85 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index c9a67c1..b6ca603 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -556,33 +556,33 @@ describe("Ray", () => { Q.compose(R).compose(S); // BEFORE .equivalent - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); - expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); - expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); - expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); - expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); - expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); - expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); - - expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); - expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); - expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); - expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); - expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); - expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); - - expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); - expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); - expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); - expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); - expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); - expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); + expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); + expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); + expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); + + expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); + expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); + expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); + expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); + expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); + + expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); + expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); + expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); + expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); + expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); + expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + + expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); + expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); + expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); + expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); + expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); + expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); /** * Drawing an equivalence between `B -> Y -> J -> R`. (Doesn't need to hold in some more abstract sense, it's just a line) @@ -598,69 +598,70 @@ describe("Ray", () => { */ B.equivalent(Y).equivalent(J)//;.equivalent(R); + // TODO: Bug is from one empty side. // TODO: Still one bug, J.# ->, makes the equiv(R) a parallel composition, so something is TERMINAL/INITIAL -> VERTEX // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); - expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); - expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); - expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); - expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); - expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); - expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); - - expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); - expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); - expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); - expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); - expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); - expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); - - expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); - expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); - expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); - expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); - expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); - expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); + expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); + expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); + expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); + + expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); + expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); + expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); + expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); + expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); + + expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); + expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); + expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); + expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); + expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); + expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + + expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); + expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); + expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); + expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); + expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); + expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); // But they should be connected through their .vertex/.self: - expect(B.dereference.is_none()).toBe(false); - expect(B.dereference.type).toBe(RayType.VERTEX); - expect(B.dereference.self).not.toBe(B.self); - expect(B.dereference.self.self.any.js).toBe('B'); - expect(B.dereference.self.any.js).toBe('___as_vertex'); - expect([...B.dereference.traverse()].length).toBe(1); - expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); - - expect(Y.dereference.is_none()).toBe(false); - expect(Y.dereference.type).toBe(RayType.VERTEX); - expect(Y.dereference.self).not.toBe(Y.self); - expect(Y.dereference.self.self.any.js).toBe('Y'); - expect(Y.dereference.self.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); - - expect(J.dereference.is_none()).toBe(false); - expect(J.dereference.type).toBe(RayType.VERTEX); - expect(J.dereference.self).not.toBe(J.self); - expect(J.dereference.self.self.any.js).toBe('J'); - expect(J.dereference.self.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); - expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); - - expect(R.dereference.is_none()).toBe(false); - expect(R.dereference.type).toBe(RayType.VERTEX); - expect(R.dereference.self).not.toBe(R.self); - expect(R.dereference.self.self.any.js).toBe('R'); - expect(R.dereference.self.any.js).toBe('___as_vertex'); - expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); - expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R']); + expect(B.dereference.is_none()).toBe(false); + expect(B.dereference.type).toBe(RayType.VERTEX); + expect(B.dereference.self).not.toBe(B.self); + expect(B.dereference.self.self.any.js).toBe('B'); + expect(B.dereference.self.any.js).toBe('___as_vertex'); + expect([...B.dereference.traverse()].length).toBe(1); + expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); + + expect(Y.dereference.is_none()).toBe(false); + expect(Y.dereference.type).toBe(RayType.VERTEX); + expect(Y.dereference.self).not.toBe(Y.self); + expect(Y.dereference.self.self.any.js).toBe('Y'); + expect(Y.dereference.self.any.js).toBe('___as_vertex'); + expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); + + expect(J.dereference.is_none()).toBe(false); + expect(J.dereference.type).toBe(RayType.VERTEX); + expect(J.dereference.self).not.toBe(J.self); + expect(J.dereference.self.self.any.js).toBe('J'); + expect(J.dereference.self.any.js).toBe('___as_vertex'); + expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); + expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); + + expect(R.dereference.is_none()).toBe(false); + expect(R.dereference.type).toBe(RayType.VERTEX); + expect(R.dereference.self).not.toBe(R.self); + expect(R.dereference.self.self.any.js).toBe('R'); + expect(R.dereference.self.any.js).toBe('___as_vertex'); + expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); + expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R']); }); test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y) ; J.equiv(J) ; Y.equiv(J)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); From ce2b7218ba8aaa06ec50a41cc7aae016d5f73e11 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 17 Jan 2024 22:41:45 +0100 Subject: [PATCH 099/138] 2024/01/17 - Fix is probably: disallow ignorant connection of A-B, reserve A.self/B.self for vertex equivalence. I'll fix that tomorrow~ --- src/@orbitmines/explorer/Ray.spec.ts | 262 ++++++++++++++++++++++++--- src/@orbitmines/explorer/Ray.ts | 46 ++++- 2 files changed, 278 insertions(+), 30 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index b6ca603..336c0a9 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -596,7 +596,7 @@ describe("Ray", () => { * [--Q--][--R--][--S--] * | */ - B.equivalent(Y).equivalent(J)//;.equivalent(R); + B.equivalent(Y).equivalent(J).equivalent(R); // TODO: Bug is from one empty side. // TODO: Still one bug, J.# ->, makes the equiv(R) a parallel composition, so something is TERMINAL/INITIAL -> VERTEX @@ -636,32 +636,130 @@ describe("Ray", () => { expect(B.dereference.self).not.toBe(B.self); expect(B.dereference.self.self.any.js).toBe('B'); expect(B.dereference.self.any.js).toBe('___as_vertex'); - expect([...B.dereference.traverse()].length).toBe(1); - expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); + expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B']); + expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); expect(Y.dereference.is_none()).toBe(false); expect(Y.dereference.type).toBe(RayType.VERTEX); expect(Y.dereference.self).not.toBe(Y.self); expect(Y.dereference.self.self.any.js).toBe('Y'); expect(Y.dereference.self.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); + expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); expect(J.dereference.is_none()).toBe(false); expect(J.dereference.type).toBe(RayType.VERTEX); expect(J.dereference.self).not.toBe(J.self); expect(J.dereference.self.self.any.js).toBe('J'); expect(J.dereference.self.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); - expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); + expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); + expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); expect(R.dereference.is_none()).toBe(false); expect(R.dereference.type).toBe(RayType.VERTEX); expect(R.dereference.self).not.toBe(R.self); expect(R.dereference.self.self.any.js).toBe('R'); expect(R.dereference.self.any.js).toBe('___as_vertex'); - expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); - expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R']); + expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); + expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R']); + }); + test("([ABC], [XYZ], [IJK]]) ; B.equiv(Y).equiv(J)", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); + const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); + const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); + + const I = Ray.vertex().o({ js: 'I' }).as_reference().o({ js: 'I.#' }); + const J = Ray.vertex().o({ js: 'J' }).as_reference().o({ js: 'J.#' }); + const K = Ray.vertex().o({ js: 'K' }).as_reference().o({ js: 'K.#' }); + + A.compose(B).compose(C); + X.compose(Y).compose(Z); + I.compose(J).compose(K); + + // BEFORE .equivalent + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); + expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); + expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); + expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); + + expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); + expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); + expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); + expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); + expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); + + expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); + expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); + expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); + expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); + expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); + expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + + /** + * Drawing an equivalence between `B -> Y -> J`. (Doesn't need to hold in some more abstract sense, it's just a line) + * | + * [--A--][--B--][--C--] + * | + * [--X--][--Y--][--Z--] + * | + * [--I--][--J--][--K--] + * | + */ + B.equivalent(Y).equivalent(J); + + // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) + expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); + expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); + expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); + expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); + expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); + + expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); + expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); + expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); + expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); + expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); + + expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); + expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); + expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); + expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); + expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); + expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + + // But they should be connected through their .vertex/.self: + expect(B.dereference.is_none()).toBe(false); + expect(B.dereference.type).toBe(RayType.VERTEX); + expect(B.dereference.self).not.toBe(B.self); + expect(B.dereference.self.self.any.js).toBe('B'); + expect(B.dereference.self.any.js).toBe('___as_vertex'); + expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(1); + expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J']); + + expect(Y.dereference.is_none()).toBe(false); + expect(Y.dereference.type).toBe(RayType.VERTEX); + expect(Y.dereference.self).not.toBe(Y.self); + expect(Y.dereference.self.self.any.js).toBe('Y'); + expect(Y.dereference.self.any.js).toBe('___as_vertex'); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); + expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J']); + + expect(J.dereference.is_none()).toBe(false); + expect(J.dereference.type).toBe(RayType.VERTEX); + expect(J.dereference.self).not.toBe(J.self); + expect(J.dereference.self.self.any.js).toBe('J'); + expect(J.dereference.self.any.js).toBe('___as_vertex'); + expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); + expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J']); }); test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y) ; J.equiv(J) ; Y.equiv(J)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -765,32 +863,32 @@ describe("Ray", () => { expect(B.dereference.self).not.toBe(B.self); expect(B.dereference.self.self.any.js).toBe('B'); expect(B.dereference.self.any.js).toBe('___as_vertex'); - expect([...B.dereference.traverse()].length).toBe(1); - expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); + expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(1); + expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); expect(Y.dereference.is_none()).toBe(false); expect(Y.dereference.type).toBe(RayType.VERTEX); expect(Y.dereference.self).not.toBe(Y.self); expect(Y.dereference.self.self.any.js).toBe('Y'); expect(Y.dereference.self.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); + expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); expect(J.dereference.is_none()).toBe(false); expect(J.dereference.type).toBe(RayType.VERTEX); expect(J.dereference.self).not.toBe(J.self); expect(J.dereference.self.self.any.js).toBe('J'); expect(J.dereference.self.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); - expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); + expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); + expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); expect(R.dereference.is_none()).toBe(false); expect(R.dereference.type).toBe(RayType.VERTEX); expect(R.dereference.self).not.toBe(R.self); expect(R.dereference.self.self.any.js).toBe('R'); expect(R.dereference.self.any.js).toBe('___as_vertex'); - expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); - expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R']); + expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); + expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R']); }); test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -880,14 +978,136 @@ describe("Ray", () => { expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['B', 'A']); }); - test(".None.#.equivalent(.vertex.#)", () => { - const A = Ray.None().as_reference(); + test("A.equiv(B) ; C.equiv(D) ; B.equiv(C)", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - // const ret = A.equivalent(B); + A.equivalent(B); + C.equivalent(D); + B.equivalent(C); - // expect() + expect(A.self.type).toBe(RayType.VERTEX); + expect(A.self.self.any.js).toBe('___as_vertex'); + expect(A.self.self.self.any.js).toBe('A'); + + expect(B.self.type).toBe(RayType.VERTEX); + expect(B.self.self.any.js).toBe('___as_vertex'); + expect(B.self.self.self.any.js).toBe('B'); + + expect(C.self.type).toBe(RayType.VERTEX); + expect(C.self.self.any.js).toBe('___as_vertex'); + expect(C.self.self.self.any.js).toBe('C'); + + expect(D.self.type).toBe(RayType.VERTEX); + expect(D.self.self.any.js).toBe('___as_vertex'); + expect(D.self.self.self.any.js).toBe('D'); + + expect([...A.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect([...A.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C', 'D']); + expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C', 'D']); + expect([...C.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); + expect([...C.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C', 'D']); + expect([...D.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['D', 'C', 'B', 'A']); + expect([...D.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['D']); }); + test("A.equiv(B).equiv(C)", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + A.equivalent(B).equivalent(C); + + expect(A.self.type).toBe(RayType.VERTEX); + expect(A.self.self.any.js).toBe('___as_vertex'); + expect(A.self.self.self.any.js).toBe('A'); + + expect(B.self.type).toBe(RayType.VERTEX); + expect(B.self.self.any.js).toBe('___as_vertex'); + expect(B.self.self.self.any.js).toBe('B'); + + expect(C.self.type).toBe(RayType.VERTEX); + expect(C.self.self.any.js).toBe('___as_vertex'); + expect(C.self.self.self.any.js).toBe('C'); + + expect([...A.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect([...A.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C']); + expect([...C.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); + expect([...C.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C']); + }); + test("A.equiv(B).equiv(C).equiv(D).equiv(E).equiv(F)", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); + const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); + const F = Ray.vertex().o({ js: 'F' }).as_reference().o({ js: 'F.#' }); + /** + * | + * [--A--] + * | + * [--B--] + * | + * [--C--] + * | + * [--D--] + * | + * [--E--] + * | + * [--F--] + * | + */ + A.equivalent(B).equivalent(C).equivalent(D).equivalent(E).equivalent(F); + + expect(A.self.type).toBe(RayType.VERTEX); + expect(A.self.self.any.js).toBe('___as_vertex'); + expect(A.self.self.self.any.js).toBe('A'); + + expect(B.self.type).toBe(RayType.VERTEX); + expect(B.self.self.any.js).toBe('___as_vertex'); + expect(B.self.self.self.any.js).toBe('B'); + + expect(C.self.type).toBe(RayType.VERTEX); + expect(C.self.self.any.js).toBe('___as_vertex'); + expect(C.self.self.self.any.js).toBe('C'); + + expect(D.self.type).toBe(RayType.VERTEX); + expect(D.self.self.any.js).toBe('___as_vertex'); + expect(D.self.self.self.any.js).toBe('D'); + + expect(E.self.type).toBe(RayType.VERTEX); + expect(E.self.self.any.js).toBe('___as_vertex'); + expect(E.self.self.self.any.js).toBe('E'); + + expect(F.self.type).toBe(RayType.VERTEX); + expect(F.self.self.any.js).toBe('___as_vertex'); + expect(F.self.self.self.any.js).toBe('F'); + + expect([...A.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect([...A.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); + expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); + expect([...C.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); + expect([...C.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C', 'D', 'E', 'F']); + expect([...D.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['D', 'C', 'B', 'A']); + expect([...D.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['D', 'E', 'F']); + expect([...E.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); + expect([...E.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['F', 'E']); + expect([...F.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); + expect([...F.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['F']); + }); + // test(".None.#.equivalent(.vertex.#)", () => { + // const A = Ray.None().as_reference(); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // + // // const ret = A.equivalent(B); + // + // // expect() + // }); test("[A, B, C][.as_array, ...]", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index ff16fe4..a97f5c1 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -164,9 +164,17 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * ______ (<- initial pointer) */ as_initial = (): Ray => { - if (this.is_none() || this.dereference.is_none()) { + if (this.is_none()) { + throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); + } + if (this.dereference.is_none()) { // TODO: Need some intuition for this check - return Ray.vertex(this.as_arbitrary()).as_reference().follow(Ray.directions.previous); + const vertex = this.___as_vertex(); + + if (vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + + return vertex.follow(Ray.directions.previous); } const [terminal_vertex, initial_vertex] = this.___as_vertices(); @@ -189,9 +197,17 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * _____ (<- terminal pointer) */ as_terminal = (): Ray => { - if (this.is_none() || this.dereference.is_none()) { + if (this.is_none()) { + throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); + } + if (this.dereference.is_none()) { // TODO: Need some intuition for this check - return Ray.vertex(this.as_arbitrary()).as_reference().follow(); + const vertex = this.___as_vertex(); + + if (vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + + return vertex.follow(); } const [initial_vertex, terminal_vertex] = this.___as_vertices(); @@ -468,15 +484,27 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * - Then we're left with the 'beginning' of one iterator, and the 'end' of the other. And the only thing that's left to do, is draw a simple (ignorant) equivalence between the two. (Basically call this function again, and call {ignorant_equivalence}). * TODO: This could also be a line with some debug information. */ - const a = initial.as_initial(); - const b = terminal.as_terminal(); + const a = initial.as_terminal(); + const b = terminal.as_initial(); - if (a.type !== RayType.INITIAL) + if (a.type !== RayType.TERMINAL) throw new PreventsImplementationBug(); - if (b.type !== RayType.TERMINAL) + if (b.type !== RayType.INITIAL) throw new PreventsImplementationBug(); - return a.equivalent(b); + if (!a.self.self.is_none()) + throw new PreventsImplementationBug(`${b.self.self.self.any.js}`); + if (!b.self.self.is_none()) + throw new PreventsImplementationBug(`${b.self.self.self.any.js}`); + + a.equivalent(b); + + const ret = terminal; + + if (ret.type !== RayType.VERTEX) + throw new PreventsImplementationBug(`${ret.type}`); + + return ret; }); equivalent = Ray.equivalent.as_method(this); From f08c1cf461608c50c567a9a02209a6b4bae97d6d Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 18 Jan 2024 17:21:22 +0100 Subject: [PATCH 100/138] 2024/01/18 - Needs a lot of cleanup, clearly some of this is not intuitive. --- src/@orbitmines/explorer/Ray.spec.ts | 390 ++++++++++++++++----------- src/@orbitmines/explorer/Ray.ts | 299 ++++++++++++-------- 2 files changed, 410 insertions(+), 279 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 336c0a9..dc08ad7 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -469,38 +469,38 @@ describe("Ray", () => { // }); - test(".None.#.equivalent(.None.#)", () => { - const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. - const B = Ray.None().o({ js: 'B' }).as_reference(); - - expect(A.type).toBe(RayType.VERTEX); - expect(B.type).toBe(RayType.VERTEX); - - expect(A.is_none()).toBe(true); - expect(A.self.any.js).toBe('A'); - expect(A.self.self.any.js).toBe('A'); - expect(A.self.self.self.any.js).toBe('A'); - - expect(B.is_none()).toBe(true); - expect(B.self.any.js).toBe('B'); - expect(B.self.self.any.js).toBe('B'); - expect(B.self.self.self.any.js).toBe('B'); - - A.equivalent(B); - - expect(A.type).toBe(RayType.REFERENCE); // Turns A into a reference to B. - expect(B.type).toBe(RayType.REFERENCE); // Turns B into a reference to A. - - expect(A.is_none()).toBe(false); - expect(A.self.any.js).toBe('A'); - expect(A.self.self.any.js).toBe('B'); - expect(A.self.self.self.any.js).toBe('A'); - - expect(B.is_none()).toBe(false); - expect(B.self.any.js).toBe('B'); - expect(B.self.self.any.js).toBe('A'); - expect(B.self.self.self.any.js).toBe('B'); - }); + // test(".None.#.equivalent(.None.#)", () => { + // const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. + // const B = Ray.None().o({ js: 'B' }).as_reference(); + // + // expect(A.type).toBe(RayType.VERTEX); + // expect(B.type).toBe(RayType.VERTEX); + // + // expect(A.is_none()).toBe(true); + // expect(A.self.any.js).toBe('A'); + // expect(A.self.self.any.js).toBe('A'); + // expect(A.self.self.self.any.js).toBe('A'); + // + // expect(B.is_none()).toBe(true); + // expect(B.self.any.js).toBe('B'); + // expect(B.self.self.any.js).toBe('B'); + // expect(B.self.self.self.any.js).toBe('B'); + // + // A.equivalent(B); + // + // expect(A.type).toBe(RayType.REFERENCE); // Turns A into a reference to B. + // expect(B.type).toBe(RayType.REFERENCE); // Turns B into a reference to A. + // + // expect(A.is_none()).toBe(false); + // expect(A.self.any.js).toBe('A'); + // expect(A.self.self.any.js).toBe('B'); + // expect(A.self.self.self.any.js).toBe('A'); + // + // expect(B.is_none()).toBe(false); + // expect(B.self.any.js).toBe('B'); + // expect(B.self.self.any.js).toBe('A'); + // expect(B.self.self.self.any.js).toBe('B'); + // }); test(".vertex.#.equivalent(.vertex.#)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); @@ -519,19 +519,22 @@ describe("Ray", () => { A.equivalent(B); expect(A.type).toBe(RayType.VERTEX); - expect(B.type).toBe(RayType.VERTEX); expect(A.self.type).toBe(RayType.VERTEX); - expect(B.self.type).toBe(RayType.VERTEX); - expect(A.is_none()).toBe(false); expect(A.self.any.js).toBe('A'); - expect(A.self.self.any.js).toBe('B'); + expect(A.self.self.any.js).toBe('___as_vertex'); expect(A.self.self.self.any.js).toBe('A'); + expect([...A.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); + expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect(B.type).toBe(RayType.VERTEX); + expect(B.self.type).toBe(RayType.VERTEX); expect(B.is_none()).toBe(false); expect(B.self.any.js).toBe('B'); - expect(B.self.self.any.js).toBe('A'); + expect(B.self.self.any.js).toBe('___as_vertex'); expect(B.self.self.self.any.js).toBe('B'); + expect([...B.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B']); + expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); }); test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y).equiv(J).equiv(R)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -890,154 +893,194 @@ describe("Ray", () => { expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R']); }); - test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - - A.equivalent(B); - - const terminal = A.as_terminal(); - - expect(terminal.type).toBe(RayType.TERMINAL); - - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); - - /** - * These should keep looping... - * TODO: Better test helper for this - */ - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['A', 'B']); - }); - test("(A:vertex.# = B:vertex.#) ; B.as_terminal", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - - A.equivalent(B); - - const terminal = B.as_terminal(); - - expect(terminal.type).toBe(RayType.TERMINAL); - - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); - - /** - * These should keep looping... - * TODO: Better test helper for this - */ - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['B', 'A']); - }); - test("(A:vertex.# = B:vertex.#) ; A.as_initial", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - - A.equivalent(B); - - const initial = A.as_initial(); - - expect(initial.type).toBe(RayType.INITIAL); - - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); - - /** - * These should keep looping... - * TODO: Better test helper for this - */ - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['A', 'B']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['A', 'B']); - }); - test("(A:vertex.# = B:vertex.#) ; B.as_initial", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - - A.equivalent(B); - - const initial = B.as_initial(); - - expect(initial.type).toBe(RayType.INITIAL); - - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); - - /** - * These should keep looping... - * TODO: Better test helper for this - */ - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['B', 'A']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['B', 'A']); - }); - test("A.equiv(B) ; C.equiv(D) ; B.equiv(C)", () => { + // test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // + // A.equivalent(B); + // + // const terminal = A.as_terminal(); + // + // expect(terminal.type).toBe(RayType.TERMINAL); + // + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); + // + // /** + // * These should keep looping... + // * TODO: Better test helper for this + // */ + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['A', 'B']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['A', 'B']); + // }); + // test("(A:vertex.# = B:vertex.#) ; B.as_terminal", () => { + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // + // A.equivalent(B); + // + // const terminal = B.as_terminal(); + // + // expect(terminal.type).toBe(RayType.TERMINAL); + // + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + // + // /** + // * These should keep looping... + // * TODO: Better test helper for this + // */ + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['B', 'A']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['B', 'A']); + // }); + // test("(A:vertex.# = B:vertex.#) ; A.as_initial", () => { + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // + // A.equivalent(B); + // + // const initial = A.as_initial(); + // + // expect(initial.type).toBe(RayType.INITIAL); + // + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); + // + // /** + // * These should keep looping... + // * TODO: Better test helper for this + // */ + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['A', 'B']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['A', 'B']); + // }); + // test("(A:vertex.# = B:vertex.#) ; B.as_initial", () => { + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // + // A.equivalent(B); + // + // const initial = B.as_initial(); + // + // expect(initial.type).toBe(RayType.INITIAL); + // + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + // + // /** + // * These should keep looping... + // * TODO: Better test helper for this + // */ + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['B', 'A']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['B', 'A']); + // }); + test("A.equiv(B).equiv(C)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - A.equivalent(B); - C.equivalent(D); - B.equivalent(C); + A.equivalent(B).equivalent(C); + expect(A.type).toBe(RayType.VERTEX); expect(A.self.type).toBe(RayType.VERTEX); + + expect(A.is_none()).toBe(false); + expect(A.self.any.js).toBe('A'); expect(A.self.self.any.js).toBe('___as_vertex'); expect(A.self.self.self.any.js).toBe('A'); + expect([...A.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect(B.type).toBe(RayType.VERTEX); expect(B.self.type).toBe(RayType.VERTEX); + expect(B.is_none()).toBe(false); + expect(B.self.any.js).toBe('B'); expect(B.self.self.any.js).toBe('___as_vertex'); expect(B.self.self.self.any.js).toBe('B'); + expect([...B.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C']); + expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect(C.type).toBe(RayType.VERTEX); expect(C.self.type).toBe(RayType.VERTEX); + expect(C.is_none()).toBe(false); + expect(C.self.any.js).toBe('C'); expect(C.self.self.any.js).toBe('___as_vertex'); expect(C.self.self.self.any.js).toBe('C'); - - expect(D.self.type).toBe(RayType.VERTEX); - expect(D.self.self.any.js).toBe('___as_vertex'); - expect(D.self.self.self.any.js).toBe('D'); - - expect([...A.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); - expect([...A.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C', 'D']); - expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); - expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C', 'D']); - expect([...C.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); - expect([...C.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C', 'D']); - expect([...D.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['D', 'C', 'B', 'A']); - expect([...D.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['D']); + expect([...C.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C']); + expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); }); - test("A.equiv(B).equiv(C)", () => { + test("A.equiv(B).equiv(C).equiv(D).equiv(E).equiv(F) ; different order", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); + const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); + const F = Ray.vertex().o({ js: 'F' }).as_reference().o({ js: 'F.#' }); - A.equivalent(B).equivalent(C); + A.equivalent(B).equivalent(C).equivalent(D); + D.equivalent(E).equivalent(F); + + expect(A.type).toBe(RayType.VERTEX); expect(A.self.type).toBe(RayType.VERTEX); + expect(A.is_none()).toBe(false); + expect(A.self.any.js).toBe('A'); expect(A.self.self.any.js).toBe('___as_vertex'); expect(A.self.self.self.any.js).toBe('A'); + expect([...A.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); + expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect(B.type).toBe(RayType.VERTEX); expect(B.self.type).toBe(RayType.VERTEX); + expect(B.is_none()).toBe(false); + expect(B.self.any.js).toBe('B'); expect(B.self.self.any.js).toBe('___as_vertex'); expect(B.self.self.self.any.js).toBe('B'); + expect([...B.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); + expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect(C.type).toBe(RayType.VERTEX); expect(C.self.type).toBe(RayType.VERTEX); + expect(C.is_none()).toBe(false); + expect(C.self.any.js).toBe('C'); expect(C.self.self.any.js).toBe('___as_vertex'); expect(C.self.self.self.any.js).toBe('C'); + expect([...C.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C', 'D', 'E', 'F']); + expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); - expect([...A.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); - expect([...A.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); - expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C']); - expect([...C.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); - expect([...C.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C']); + expect(D.type).toBe(RayType.VERTEX); + expect(D.self.type).toBe(RayType.VERTEX); + expect(D.is_none()).toBe(false); + expect(D.self.any.js).toBe('D'); + expect(D.self.self.any.js).toBe('___as_vertex'); + expect(D.self.self.self.any.js).toBe('D'); + expect([...D.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['D', 'E', 'F']); + expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['D', 'C', 'B', 'A']); + + expect(E.type).toBe(RayType.VERTEX); + expect(E.self.type).toBe(RayType.VERTEX); + expect(E.is_none()).toBe(false); + expect(E.self.any.js).toBe('E'); + expect(E.self.self.any.js).toBe('___as_vertex'); + expect(E.self.self.self.any.js).toBe('E'); + expect([...E.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['E', 'F']); + expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); + + expect(F.type).toBe(RayType.VERTEX); + expect(F.self.type).toBe(RayType.VERTEX); + expect(F.is_none()).toBe(false); + expect(F.self.any.js).toBe('F'); + expect(F.self.self.any.js).toBe('___as_vertex'); + expect(F.self.self.self.any.js).toBe('F'); + expect([...F.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['F']); + expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); }); test("A.equiv(B).equiv(C).equiv(D).equiv(E).equiv(F)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -1046,6 +1089,7 @@ describe("Ray", () => { const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); const F = Ray.vertex().o({ js: 'F' }).as_reference().o({ js: 'F.#' }); + /** * | * [--A--] @@ -1063,42 +1107,60 @@ describe("Ray", () => { */ A.equivalent(B).equivalent(C).equivalent(D).equivalent(E).equivalent(F); + expect(A.type).toBe(RayType.VERTEX); expect(A.self.type).toBe(RayType.VERTEX); + + expect(A.is_none()).toBe(false); + expect(A.self.any.js).toBe('A'); expect(A.self.self.any.js).toBe('___as_vertex'); expect(A.self.self.self.any.js).toBe('A'); + expect([...A.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); + expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect(B.type).toBe(RayType.VERTEX); expect(B.self.type).toBe(RayType.VERTEX); + expect(B.is_none()).toBe(false); + expect(B.self.any.js).toBe('B'); expect(B.self.self.any.js).toBe('___as_vertex'); expect(B.self.self.self.any.js).toBe('B'); + expect([...B.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); + expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect(C.type).toBe(RayType.VERTEX); expect(C.self.type).toBe(RayType.VERTEX); + expect(C.is_none()).toBe(false); + expect(C.self.any.js).toBe('C'); expect(C.self.self.any.js).toBe('___as_vertex'); expect(C.self.self.self.any.js).toBe('C'); + expect([...C.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C', 'D', 'E', 'F']); + expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); + expect(D.type).toBe(RayType.VERTEX); expect(D.self.type).toBe(RayType.VERTEX); + expect(D.is_none()).toBe(false); + expect(D.self.any.js).toBe('D'); expect(D.self.self.any.js).toBe('___as_vertex'); expect(D.self.self.self.any.js).toBe('D'); + expect([...D.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['D', 'E', 'F']); + expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['D', 'C', 'B', 'A']); + expect(E.type).toBe(RayType.VERTEX); expect(E.self.type).toBe(RayType.VERTEX); + expect(E.is_none()).toBe(false); + expect(E.self.any.js).toBe('E'); expect(E.self.self.any.js).toBe('___as_vertex'); expect(E.self.self.self.any.js).toBe('E'); + expect([...E.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['E', 'F']); + expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); + expect(F.type).toBe(RayType.VERTEX); expect(F.self.type).toBe(RayType.VERTEX); + expect(F.is_none()).toBe(false); + expect(F.self.any.js).toBe('F'); expect(F.self.self.any.js).toBe('___as_vertex'); expect(F.self.self.self.any.js).toBe('F'); - - expect([...A.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); - expect([...A.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); - expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); - expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); - expect([...C.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); - expect([...C.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C', 'D', 'E', 'F']); - expect([...D.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['D', 'C', 'B', 'A']); - expect([...D.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['D', 'E', 'F']); - expect([...E.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); - expect([...E.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['F', 'E']); - expect([...F.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); - expect([...F.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['F']); + expect([...F.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['F']); + expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); }); // test(".None.#.equivalent(.vertex.#)", () => { // const A = Ray.None().as_reference(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index a97f5c1..ba8d32d 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -157,89 +157,89 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ get dereference() { return this.self.self.as_reference(); } - /** - * Moves `this.self` and `this.self.self` to a new line. - * - * [ |--] this.self ----- this.self.self [--|--] - * ______ (<- initial pointer) - */ - as_initial = (): Ray => { - if (this.is_none()) { - throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); - } - if (this.dereference.is_none()) { - // TODO: Need some intuition for this check - const vertex = this.___as_vertex(); - - if (vertex.type !== RayType.VERTEX) - throw new PreventsImplementationBug(); - - return vertex.follow(Ray.directions.previous); - } - - const [terminal_vertex, initial_vertex] = this.___as_vertices(); - - if (initial_vertex.type !== RayType.VERTEX) - throw new PreventsImplementationBug(); - if (terminal_vertex.type !== RayType.VERTEX) - throw new PreventsImplementationBug(); - - initial_vertex.compose(terminal_vertex); - - // TODO BETTER DEBUG - - return initial_vertex.follow(Ray.directions.previous); - } - /** - * Moves `this.self` and `this.self.self` to a new line. - * - * [ |--] this.self.self ----- this.self [--|--] - * _____ (<- terminal pointer) - */ - as_terminal = (): Ray => { - if (this.is_none()) { - throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); - } - if (this.dereference.is_none()) { - // TODO: Need some intuition for this check - const vertex = this.___as_vertex(); - - if (vertex.type !== RayType.VERTEX) - throw new PreventsImplementationBug(); - - return vertex.follow(); - } - - const [initial_vertex, terminal_vertex] = this.___as_vertices(); - - if (initial_vertex.type !== RayType.VERTEX) - throw new PreventsImplementationBug(); - if (terminal_vertex.type !== RayType.VERTEX) - throw new PreventsImplementationBug(); - - initial_vertex.compose(terminal_vertex); - - // TODO BETTER DEBUG - - return terminal_vertex.follow(); - } - private ___as_vertices = (): [Ray, Ray] => { - if (!Ray.is_orbit(this.self, this.self.self.self)) - throw new PreventsImplementationBug('Is there a use-case for this? Probably not?'); //TODO - - // TODO NOTE: THE ORDER OF `this.self` first matters here. - return [this.self.___as_vertex(), this.___as_vertex()]; - } - private ___as_vertex = (): Ray => { - const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); - - // this.self.self = vertex.self.as_arbitrary(); - // vertex.self.self = this.self.as_arbitrary(); - - // return this.___ignorantly_equivalent(Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' })); - - return this.___ignorantly_equivalent(vertex); - } + // /** + // * Moves `this.self` and `this.self.self` to a new line. + // * + // * [ |--] this.self ----- this.self.self [--|--] + // * ______ (<- initial pointer) + // */ + // as_initial = (): Ray => { + // if (this.is_none()) { + // throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); + // } + // if (this.dereference.is_none()) { + // // TODO: Need some intuition for this check + // const vertex = this.___as_vertex(); + // + // if (vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // return vertex.follow(Ray.directions.previous); + // } + // + // const [terminal_vertex, initial_vertex] = this.___as_vertices(); + // + // if (initial_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // if (terminal_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // initial_vertex.compose(terminal_vertex); + // + // // TODO BETTER DEBUG + // + // return initial_vertex.follow(Ray.directions.previous); + // } + // /** + // * Moves `this.self` and `this.self.self` to a new line. + // * + // * [ |--] this.self.self ----- this.self [--|--] + // * _____ (<- terminal pointer) + // */ + // as_terminal = (): Ray => { + // if (this.is_none()) { + // throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); + // } + // if (this.dereference.is_none()) { + // // TODO: Need some intuition for this check + // const vertex = this.___as_vertex(); + // + // if (vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // return vertex.follow(); + // } + // + // const [initial_vertex, terminal_vertex] = this.___as_vertices(); + // + // if (initial_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // if (terminal_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // initial_vertex.compose(terminal_vertex); + // + // // TODO BETTER DEBUG + // + // return terminal_vertex.follow(); + // } + // private ___as_vertices = (): [Ray, Ray] => { + // if (!Ray.is_orbit(this.self, this.self.self.self)) + // throw new PreventsImplementationBug('Is there a use-case for this? Probably not?'); //TODO + // + // // TODO NOTE: THE ORDER OF `this.self` first matters here. + // return [this.self.___as_vertex(), this.___as_vertex()]; + // } + // private ___as_vertex = (): Ray => { + // const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + // + // // this.self.self = vertex.self.as_arbitrary(); + // // vertex.self.self = this.self.as_arbitrary(); + // + // // return this.___ignorantly_equivalent(Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' })); + // + // return this.___ignorantly_equivalent(vertex); + // } private ___ignorantly_equivalent = (ref: Ray): Ray => { this.self.self = ref.self.as_arbitrary(); ref.self.self = this.self.as_arbitrary(); @@ -435,6 +435,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }); compose = Ray.compose.as_method(this); + // TODO: Cleanup /** * Equivalence as "Composing Vertices": "TODO: Is this right?: Equivalence at Continuations, inside a Vertex, is parallel composition, from the perspective of the usual direction defined at the Vertex (not generally parallel)" * - `A.equivalent(B)` = `A.as_vertex().compose(B.as_vertex())` @@ -462,52 +463,120 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } // 2x Ray.None -> Turn into 2 empty references, referencing each-other. - if (initial.is_none() && terminal.is_none()) + if ( + initial.dereference.is_none() && terminal.dereference.is_none() + && !(initial.type === RayType.VERTEX && terminal.type === RayType.VERTEX) + ) { + // throw new PreventsImplementationBug(`${initial.type} / ${terminal.type}`) return ignorant_equivalence(); + } - // Two structures, which have `ref.self = Ray.None` -> Turn into two structures referencing each-other. - if (initial.dereference.is_none() && terminal.dereference.is_none()) - return ignorant_equivalence(); + // Two structures, which have `ref.self = Ray.None` -> Turn into two structures which are on a line in between them. + if (initial.dereference.is_none()) { + const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + vertex.self.self = initial.self.as_arbitrary(); + initial.self.self = vertex.self.as_arbitrary(); - if ( - (initial.is_vertex() && terminal.is_boundary()) - || (terminal.is_vertex() && initial.is_boundary()) - ) { - throw new NotImplementedError(`Parallel composition: TODO`); + // initial.equivalent(terminal); + // return terminal; } + if (terminal.dereference.is_none()) { + const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + vertex.self.self = terminal.self.as_arbitrary(); + terminal.self.self = vertex.self.as_arbitrary(); - /** - * - Splits the 'initial' side's vertex, into an iterable one, and returns a pointer to the initial side of that iterator. - * - * - Similarly, we do the opposite for the terminal, returning the terminal side of that iterator. - * - * - Then we're left with the 'beginning' of one iterator, and the 'end' of the other. And the only thing that's left to do, is draw a simple (ignorant) equivalence between the two. (Basically call this function again, and call {ignorant_equivalence}). - * TODO: This could also be a line with some debug information. - */ - const a = initial.as_terminal(); - const b = terminal.as_initial(); + // initial.equivalent(terminal.___as_vertex()); + // return terminal; + } - if (a.type !== RayType.TERMINAL) - throw new PreventsImplementationBug(); - if (b.type !== RayType.INITIAL) - throw new PreventsImplementationBug(); + if ( + initial.dereference.type !== RayType.VERTEX + || terminal.dereference.type !== RayType.VERTEX + || initial.dereference.self === initial.self + || terminal.dereference.self === terminal.self + ) { + throw new PreventsImplementationBug('wut') + } - if (!a.self.self.is_none()) - throw new PreventsImplementationBug(`${b.self.self.self.any.js}`); - if (!b.self.self.is_none()) - throw new PreventsImplementationBug(`${b.self.self.self.any.js}`); + if (initial.follow().type !== RayType.TERMINAL || terminal.follow(Ray.directions.previous).type !== RayType.INITIAL) { + throw new PreventsImplementationBug('wut2') + } - a.equivalent(b); + // if (terminal.self.self.any.js === 'D') + // throw new PreventsImplementationBug(); - const ret = terminal; + initial.dereference.compose(terminal.dereference); - if (ret.type !== RayType.VERTEX) - throw new PreventsImplementationBug(`${ret.type}`); + return terminal; - return ret; + // initial.dereference.compose() + // return terminal; }); equivalent = Ray.equivalent.as_method(this); + // static equivalent = Ray.___func(ref => { + // let { initial, terminal} = ref.self; + // + // /** + // * The simplest case, is where both sides are only aware of themselves (on .vertex). The only thing we need to do is turn an Orbit, to an Orbit which repeats every 2 steps, the intermediate step being the other thing. + // * + // * Or in textual terms something like: + // * - A single Orbit: `(A.self = A) | (B.self = B)` (i.e. A.is_none && B.is_none) + // * - To: `(A.self = B) | (B.self = A)` + // * + // * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. + // */ + // const ignorant_equivalence = (): Ray => { + // return initial.___ignorantly_equivalent(terminal); + // } + // + // // 2x Ray.None -> Turn into 2 empty references, referencing each-other. + // if (initial.is_none() && terminal.is_none()) + // return ignorant_equivalence(); + // + // // Two structures, which have `ref.self = Ray.None` -> Turn into two structures referencing each-other. + // if (initial.dereference.is_none() && terminal.dereference.is_none()) + // return ignorant_equivalence(); + // + // if ( + // (initial.is_vertex() && terminal.is_boundary()) + // || (terminal.is_vertex() && initial.is_boundary()) + // ) { + // throw new NotImplementedError(`Parallel composition: TODO`); + // } + // + // /** + // * - Splits the 'initial' side's vertex, into an iterable one, and returns a pointer to the initial side of that iterator. + // * + // * - Similarly, we do the opposite for the terminal, returning the terminal side of that iterator. + // * + // * - Then we're left with the 'beginning' of one iterator, and the 'end' of the other. And the only thing that's left to do, is draw a simple (ignorant) equivalence between the two. (Basically call this function again, and call {ignorant_equivalence}). + // * TODO: This could also be a line with some debug information. + // */ + // const a = initial.as_terminal(); + // const b = terminal.as_initial(); + // + // if (a.type !== RayType.TERMINAL) + // throw new PreventsImplementationBug(); + // if (b.type !== RayType.INITIAL) + // throw new PreventsImplementationBug(); + // + // if (!a.self.self.is_none()) + // throw new PreventsImplementationBug(`${b.self.self.self.any.js}`); + // if (!b.self.self.is_none()) + // throw new PreventsImplementationBug(`${b.self.self.self.any.js}`); + // + // a.equivalent(b); + // + // const ret = terminal; + // + // if (ret.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(`${ret.type}`); + // + // return ret; + // }); + // equivalent = Ray.equivalent.as_method(this); + // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... // [[a,d,g],[b,e,h],[c,f,i]] From 1b7a18112f22e50155cf40818092b39a29147728 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 18 Jan 2024 17:33:21 +0100 Subject: [PATCH 101/138] 2024/01/18 - Test cleanup --- src/@orbitmines/explorer/Ray.spec.ts | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index dc08ad7..7cfe5d3 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -27,7 +27,7 @@ describe("Ray", () => { A.compose(B).compose(C); - expect(() => A.copy()).toThrow(); + expect(() => A.copy()).toThrow(); //TODO // const copy = A.copy(); // expect(A.has_previous()).toBe(false); // expect(copy.has_previous()).toBe(false); @@ -357,19 +357,6 @@ describe("Ray", () => { expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X', 'C', 'B', 'A']); expect([...X].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); }); - // test("(A:vertex.# = B:vertex.# = C:vertex.#)", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - // // const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - // - // A.equivalent(B).equivalent(C); - // // C.equivalent(D); - // - // // A.equivalent(D); - // // A.equivalent(C); - // - // }); // test("[A, B, C], [X, Y, Z] ; B.compose(X)", () => { // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); @@ -1178,7 +1165,7 @@ describe("Ray", () => { A.compose(B).compose(C); expect(A.as_array().map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); // TODO: This may or may not be expected behavior, you could make a case for saying it should render both sides for .as_array. ??? + expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); expect(C.as_array().map(ref => ref.self.any.js)).toEqual(['C']); expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); @@ -1265,7 +1252,7 @@ describe("Ray", () => { .any.js ).toBe('B'); }); - // test(".vertex.#.debug", () => { + // test(".vertex.#.debug", () => { TODO // const a = Ray.vertex().as_reference(); // const b = Ray.vertex().as_reference(); // a.compose(b); @@ -1302,14 +1289,6 @@ describe("Ray", () => { expect(ray.any.position).toEqual([0, 1, 2]); expect(ray.any.func()).toBe('c'); }) - - // test(".[vertex, vertex].#.compose", () => { - // /** [--|--] */ const vertex = Ray.vertex().as_reference(); - // vertex.initial.o({ js: 'A' }); - // vertex.terminal.o({ js: 'B' }); - // - // expect(vertex.compose.) - // }); test(".vertex.#", () => { /** [--|--] */ const vertex = Ray.vertex().as_reference(); From 6eb96c2ead27a686e7b5ae7ae8d59c55bf026710 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 18 Jan 2024 22:41:55 +0100 Subject: [PATCH 102/138] 2024/01/18 - Some fixes, iterating on .traverse/.next for the arbitrary structures. --- src/@orbitmines/explorer/Ray.spec.ts | 56 +++ src/@orbitmines/explorer/Ray.ts | 442 ++++++++++++------ src/@orbitmines/external/chyp/Chyp.spec.ts | 4 +- src/@orbitmines/external/chyp/Chyp.ts | 43 ++ .../external/chyp/Chyp_naive_pass.ts | 158 ++++--- 5 files changed, 480 insertions(+), 223 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 7cfe5d3..ac6b209 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -32,6 +32,62 @@ describe("Ray", () => { // expect(A.has_previous()).toBe(false); // expect(copy.has_previous()).toBe(false); }); + test(".vertex.#.delete", () => { + const A_vertex = Ray.vertex().o({ js: 'A' }); + const A_ref = A_vertex.as_reference().o({ js: 'A.#' }); + + expect(A_vertex.is_none()).toBe(false); + expect(A_ref.follow().is_none()).toBe(false); + expect(A_ref.follow(Ray.directions.previous).is_none()).toBe(false); + expect(A_vertex.any.js).toBe('A'); + expect(A_ref.is_none()).toBe(false); + + A_ref.delete(); + + expect(A_vertex.is_none()).toBe(true); + expect(A_vertex.follow().is_none()).toBe(true); + expect(A_vertex.follow(Ray.directions.previous).is_none()).toBe(true); + expect(A_vertex.any.js).toBe(undefined); + expect(A_ref.is_none()).toBe(true); + }); + test("[A, B, C].___next()", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); + const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); + + A.compose(B).compose(C).compose(D).compose(E); + + expect([...A.___next()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E']); + }); + test("[A, B, C].___traverse()", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); + const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); + + A.compose(B).compose(C).compose(D).compose(E); + + expect([...A.___traverse()].map(pointer => + [pointer.initial.type, pointer.terminal.type, pointer.initial.self.any.js] + )).toEqual([ + [RayType.VERTEX, RayType.TERMINAL, 'A'], + [RayType.TERMINAL, RayType.INITIAL, undefined], + [RayType.INITIAL, RayType.VERTEX, undefined], + [RayType.VERTEX, RayType.TERMINAL, 'B'], + [RayType.TERMINAL, RayType.INITIAL, undefined], + [RayType.INITIAL, RayType.VERTEX, undefined], + [RayType.VERTEX, RayType.TERMINAL, 'C'], + [RayType.TERMINAL, RayType.INITIAL, undefined], + [RayType.INITIAL, RayType.VERTEX, undefined], + [RayType.VERTEX, RayType.TERMINAL, 'D'], + [RayType.TERMINAL, RayType.INITIAL, undefined], + [RayType.INITIAL, RayType.VERTEX, undefined], + [RayType.VERTEX, RayType.TERMINAL, 'E'], + ]); + }); test("[A, B, C].next()", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index ba8d32d..840cba3 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -2,7 +2,6 @@ import _ from "lodash"; import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; - // TODO: SHOULDNT CLASSIFY THESE? (And incorporate in Ray??) export enum RayType { // NONE = ' ', @@ -80,9 +79,16 @@ export type DebugRay = { * * * + * TODO: All methods to 'step' variant - and an intuitive way to switch between modes + * - Through better Ray.___func + * - Transform all functions on Ray to that. (Perhaps use JavaScript generators by default (more intuitively?) - Just convert using JS.Generator) + * - No assumption of halting + * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence * + * TODO: Stylistic + * - Consistency of Arbitrary vs non-arbitrary. + * - Reorder methods in a sensible way. * - * TODO: Consistency of Arbitrary vs non-arbitrary. */ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? implements @@ -269,122 +275,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO: Difference between () => this & this.as_arbitrary , relevant for lazy/modular/ignorant structures etc.. as_arbitrary = (): Arbitrary => () => this; - /** - * - * - * TODO: switch/match Should be abstracted into Ray? - */ - static step = (ref: Ray) => { - const { initial } = ref; - - /** - * Should return vertex, for one possible next step - * Initial for many - * Terminal for none - * Reference for ??? - */ - - /** - * Dereferencing is likely in many cases quickly subject to infinite stepping. - * - * REFERENCE -> Dereference (this.self.self) - * INITIAL/INITIAL -> Dereference (this.self.terminal) - * TERMINAL/TERMINAL -> Dereference (this.self.initial) - * VERTEX/VERTEX -> ??? - * - * - Could be that this means that there's no continuation, a self-reference defined here, or it's some mechanism of halting. - * - * - TODO: Simple example of infinitely finding terminals, or a reference to 'nothing - infinitely'. - * - TODO: Could return both dereference sides as possible options - */ - - const next_pointer = (ref: Ray, terminal: Ray, next: Arbitrary) => new Ray({ - initial: () => terminal, - vertex: () => ref, - terminal: next, - }); - - /** - * INITIAL/TERMINAL -> possible previous - TERMINAL.self.initial (pass to step) - * TERMINAL/INITIAL -> possible next - INITIAL.self.terminal (pass to step) - */ - const follow_direction = (terminal: Ray): Ray => next_pointer(ref, terminal, () => terminal.___primitive_switch({ - [RayType.INITIAL]: Ray.directions.next, - [RayType.TERMINAL]: Ray.directions.previous, - })); - - const dereference = (terminal: Ray) => next_pointer(ref, terminal, () => terminal.dereference); - - /** - * TERMINAL -> VERTEX (next: VERTEX -> INITIAL) - * INITIAL -> VERTEX (next: VERTEX -> TERMINAL) - */ - const arbitrary_continuations = (terminal: Ray): Ray => next_pointer(ref, terminal, () => initial.___primitive_switch({ - [RayType.INITIAL]: (initial) => Ray.directions.next(terminal), - [RayType.TERMINAL]: (initial) => Ray.directions.previous(terminal), - })); - - const boundary = (boundary: Boundary) => (terminal: Ray): Ray => terminal.___primitive_switch({ - - /** - * Many possible continuations (from the perspective of initial = TERMINAL) - * - * From something, we arrived at some TERMINAL/INITIAL, which at its `.self`, holds a VERTEX. - * [ ? ] - * [--|--][--| ] <-- ref superposed with ref.self - * [ ? ] - */ - [RayType.VERTEX]: arbitrary_continuations, - - /** - * A possible continuation - * - * (INITIAL -> TERMINAL) - * (TERMINAL -> INITIAL) - */ - [boundary]: follow_direction, - [opposite(boundary)]: follow_direction, - - [RayType.REFERENCE]: dereference, - }); - - return initial.___primitive_switch({ - - /** - * VERTEX -> VERTEX - * TODO Could be an ignorant continuation (as in, the terminal does not have the initial vertex on its .initial). Or you could interpret this as saying, oh this should be a vertex, no information about the continuation definition in between? - * - * VERTEX -> TERMINAL - * If we're going in the terminal direction (from the perspective of the initial = VERTEX) - * [--|--][--| ] <-- (VERTEX -> TERMINAL) - * - * VERTEX -> INITIAL - * If we're going in the initial direction (from the perspective of the initial = VERTEX) - * [ |--][--|--] <-- (VERTEX -> INITIAL) - * - * VERTEX -> REFERENCE - * TODO ??? - */ - [RayType.VERTEX]: (initial) => dereference(ref.terminal), - - [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL)(ref.terminal), - [RayType.TERMINAL]: (initial) => boundary(RayType.TERMINAL)(ref.terminal), - - [RayType.REFERENCE]: dereference, - }); - } - step= Ray.___func(Ray.step).as_method(this); - - // TODO; Maybe replace switch with 'zip'?, What are the practical differences? - protected ___primitive_switch = (cases: SwitchCases): Ray => { - const _case = cases[this.type]; - - if (_case === undefined || _.isString(_case)) - throw new PreventsImplementationBug(_case ?? `Unhandled switch case; [${this.type}]`); - - return _case(this); - } - /** * TODO : COMPOSE EMPTY AS FIRST ELEMENT: * if (initial.is_none()) { @@ -580,8 +470,26 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... // [[a,d,g],[b,e,h],[c,f,i]] - zip = (): Ray => { throw new NotImplementedError(); } + static zip = Ray.___func(ref => { + let { initial, terminal } = ref.self; + + if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) + throw new PreventsImplementationBug('TODO: Implement'); + + if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) + throw new PreventsImplementationBug('TODO: Implement'); + + throw new NotImplementedError(); + // initial.traverse() + // return new Ray({ + // + // }); + }); + zip = Ray.zip.as_method(this); + // pop = (): Ray => { + // this.last().previous().all.terminal = (ref) => ref.___empty_terminal(); + // } pop = (): Ray => this.___primitive_switch({ [RayType.VERTEX]: () => { const previous_vertex = this.self.initial.follow(Ray.directions.previous); @@ -602,6 +510,16 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } }); + + // static sn = (step: Implementation): { + // as_method: ArbitraryMethod + // } => { + // + // return { + // as_method: Ray.___func(step).as_method + // } + // } + /** * Constructs a function accepting arbitrary structure based on one implementation of it. * @@ -684,7 +602,13 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * .next */ - next = (step: Implementation = Ray.directions.next) => { + next = (step: Implementation = Ray.directions.next): Ray => { + // for (let next of this.___next({step})) { + // + // // return next; + // } + // + // return Ray.None(); let pointer = new Ray({ initial: () => this, terminal: () => step(this), @@ -724,8 +648,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? is_equivalent = (b: Ray): boolean => { return false; } // TODOl: Current references assume you can't go inside vertex.. // TODO implement .not?? - // TODO: Perhaps locally cache count?? - no way to ensure globally coherenct - get count(): Ray { throw new NotImplementedError() } + get count(): Ray { return JS.Number(this.as_array().length); } // TODO; Could return the ignorant reference to both instances, or just the result., .. @@ -756,7 +679,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // return copy.as_reference(); } - none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); + // none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); // @alias('converse', 'opposite', 'swap') get reverse(): Ray { @@ -834,7 +757,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } - all = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } // filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } get clear(): Ray { throw new NotImplementedError(); } @@ -854,7 +776,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? max = (_default: 0): Ray => { throw new NotImplementedError(); } // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS - apply = (func: Ray) => { + // apply = (func: Ray) => { // TODO: Combine into generalized [x, min/max()] - preserve terminal/initial structure // TODO: ray#apply. @@ -870,7 +792,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * compose.initial.x.max(), // max_self * ] */ - } + // } // ___compute = () @@ -880,18 +802,229 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (this.type !== RayType.VERTEX) throw new NotImplementedError(`[${this.type}]`); - let current: Ray = this; + yield *this.___next({step}); + } + + static pointer = (initial: Ray, step: Implementation): Ray => new Ray({ + initial: () => initial, + terminal: () => step(initial) + }); + + private next_pointer = (step: Implementation) => { + const { self: history, terminal: current } = this; + + return new Ray({ + initial: current.as_arbitrary(), + vertex: history.as_arbitrary(), + terminal: () => current.follow(step) + }); + }; + + /** + * VERTEX (current) + * | + * v + * + * ? <-- Pointer B + * [--| ] <-- INITIAL/TERMINAL (previous) + * ? <-- Pointer A + */ + private branch = (): [Ray, Ray] => { + const { initial: previous, terminal: current } = this; + + if (!previous.is_boundary()) + throw new PreventsImplementationBug('Only branching off INITIAL/TERMINAL -> VERTEX for now.'); + if (current.type !== RayType.VERTEX) + throw new PreventsImplementationBug('Only branching off INITIAL/TERMINAL -> VERTEX for now.'); + + return [ + this.next_pointer(Ray.directions.previous), + this.next_pointer(Ray.directions.next) + ]; + } + + *___next({ + step = Ray.directions.next, + } = {}): Generator { + for (let pointer of this.___traverse({step})) { + + // TODO: You can do this non-locally with a pass over the history. This way it's local, but we''ll have to find a good example of why this might not go that well. (As this would match to any empty vertices, and maybe more) + const { initial: previous, terminal: current } = pointer; + + if (previous.is_vertex() && !Ray.is_orbit(previous.self, current)) { + yield pointer.initial; + } + } + } + + /** + * TODO: Not happy with this... + */ + *___traverse({ + step = Ray.directions.next, + should_branch = (pointer: Ray) => { + const { initial: previous, terminal: current } = pointer; + return previous.is_boundary() && current.is_vertex() && Ray.is_orbit(current.self, previous); + }, + branch = (pointer: Ray): [Ray, Ray] => pointer.branch(), + filter = (pointer: Ray): boolean => true, + next = (pointers: Ray[]): Ray => pointers[0], + remove = (pointers: Ray[], pointer: Ray) => delete pointers[0], + } = {}): Generator { + const pointers: Ray[] = [ + Ray.vertex(Ray.pointer(this, step).as_arbitrary()) + ]; // TODO COuld be a ray; while (true) { - yield current; - if (!current.has_next(step)) + const ref = next(pointers); + if (ref === undefined) { + // TODO: Could just keep trying... break; + } + let { self: pointer } = ref; + + if (!filter(pointer)) { + remove(pointers, pointer); + continue; + } + + yield pointer; + + pointer = pointer.step(); - current = current.next(step); + if (pointer.terminal.is_none()) { + remove(pointers, pointer); + continue; + } + + if (should_branch(pointer)) { + const [a, b] = branch(pointer); + + ref.self = a.as_arbitrary(); + pointers.push(Ray.vertex(b.as_arbitrary())); + } else { + ref.self = pointer.as_arbitrary(); + } } } + /** + * + * + * TODO: switch/match Should be abstracted into Ray? + */ + static step = (ref: Ray) => { + const { initial } = ref; + + /** + * Should return vertex, for one possible next step + * Initial for many + * Terminal for none + * Reference for ??? + */ + + /** + * Dereferencing is likely in many cases quickly subject to infinite stepping. + * + * REFERENCE -> Dereference (this.self.self) + * INITIAL/INITIAL -> Dereference (this.self.terminal) + * TERMINAL/TERMINAL -> Dereference (this.self.initial) + * VERTEX/VERTEX -> ??? + * + * - Could be that this means that there's no continuation, a self-reference defined here, or it's some mechanism of halting. + * + * - TODO: Simple example of infinitely finding terminals, or a reference to 'nothing - infinitely'. + * - TODO: Could return both dereference sides as possible options + */ + + const next_pointer = (terminal: Ray, next: Arbitrary) => new Ray({ + initial: () => terminal, + vertex: () => ref, + terminal: next, + }); + + /** + * INITIAL/TERMINAL -> possible previous - TERMINAL.self.initial (pass to step) + * TERMINAL/INITIAL -> possible next - INITIAL.self.terminal (pass to step) + */ + const follow_direction = (terminal: Ray): Ray => next_pointer(terminal, () => terminal.___primitive_switch({ + [RayType.INITIAL]: Ray.directions.next, + [RayType.TERMINAL]: Ray.directions.previous, + })); + + const dereference = (terminal: Ray) => next_pointer(terminal, () => terminal.dereference); + + /** + * TERMINAL -> VERTEX (next: VERTEX -> INITIAL) + * INITIAL -> VERTEX (next: VERTEX -> TERMINAL) + */ + const arbitrary_continuations = (terminal: Ray): Ray => next_pointer(terminal, () => initial.___primitive_switch({ + [RayType.INITIAL]: (initial) => Ray.directions.next(terminal), + [RayType.TERMINAL]: (initial) => Ray.directions.previous(terminal), + })); + + const boundary = (boundary: Boundary) => (terminal: Ray): Ray => terminal.___primitive_switch({ + + /** + * Many possible continuations (from the perspective of initial = TERMINAL) + * + * From something, we arrived at some TERMINAL/INITIAL, which at its `.self`, holds a VERTEX. + * [ ? ] + * [--|--][--| ] <-- ref superposed with ref.self + * [ ? ] + */ + [RayType.VERTEX]: arbitrary_continuations, + + /** + * A possible continuation + * + * (INITIAL -> TERMINAL) + * (TERMINAL -> INITIAL) + */ + [boundary]: follow_direction, + [opposite(boundary)]: follow_direction, + + [RayType.REFERENCE]: dereference, + }); + + return initial.___primitive_switch({ + + /** + * VERTEX -> VERTEX + * TODO Could be an ignorant continuation (as in, the terminal does not have the initial vertex on its .initial). Or you could interpret this as saying, oh this should be a vertex, no information about the continuation definition in between? + * + * VERTEX -> TERMINAL + * If we're going in the terminal direction (from the perspective of the initial = VERTEX) + * [--|--][--| ] <-- (VERTEX -> TERMINAL) + * + * VERTEX -> INITIAL + * If we're going in the initial direction (from the perspective of the initial = VERTEX) + * [ |--][--|--] <-- (VERTEX -> INITIAL) + * + * VERTEX -> REFERENCE + * TODO ??? + */ + [RayType.VERTEX]: (initial) => dereference(ref.terminal), + + [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL)(ref.terminal), + [RayType.TERMINAL]: (initial) => boundary(RayType.TERMINAL)(ref.terminal), + + [RayType.REFERENCE]: dereference, + }); + } + step= Ray.___func(Ray.step).as_method(this); + + // TODO; Maybe replace switch with 'zip'?, What are the practical differences? + protected ___primitive_switch = (cases: SwitchCases): Ray => { + const _case = cases[this.type]; + + if (_case === undefined || _.isString(_case)) + throw new PreventsImplementationBug(_case ?? `Unhandled switch case; [${this.type}]`); + + return _case(this); + } + /** * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. */ @@ -916,11 +1049,14 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_int = (): number => { throw new NotImplementedError(); } as_number = this.as_int; + // all = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + // get all(): { [key: string | symbol]: Ray } & any { return this.proxy(); } + /** * Move to a JavaScript object, which will handle any complexity of existing JavaScript objects, and allows one to abstract any values contained in the {vertex} to the usual JavaScript interface. - More usual to how one thinks about functions, ..., properties. */ get any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } - cast = (): T => this.proxy(); + cast = (): T => { throw new NotImplementedError(); } // TODO this.proxy(); /** * Used for chaining JavaScript-provided properties @@ -946,6 +1082,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? protected proxy = (constructor?: ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: // TODO: IMPLEMENT SPLAT... {...ray.any} return this._proxy ??= new Proxy(this, { + get(self: Ray, p: string | symbol, receiver: any): any { // throw new NotImplementedError(); @@ -957,14 +1094,39 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? self._dirty_store[p] = newValue; return true; - } + }, + + deleteProperty(self: Ray, p: string | symbol): boolean { + if (!(p in self._dirty_store)) { + return false; + } + delete self._dirty_store[p]; + return true; + } // TODO: What do these other methods on Proxy do??? }) as T; } - get delete(): Ray { - this.self = Ray.None; // TODO; I made a lazy delete comment somewhere? + /** + * + * - Don't assume we can track back any reference to this thing. Just destroy it, set everything to None. And let anything else deal with the consequences of the deletion. + * + * TODO: + * - Could lazily try to find references. + * - Implement on proxy for 'delete ray' + */ + delete = (): Ray => { + this.self.initial = Ray.None; + this.self.self = this.self.self_reference; + this.self.terminal = Ray.None; + // TODO: REMOVE THESE + this.self._proxy = undefined; + this.self._dirty_store = {}; + + // Removes the current reference to it. + this.self = this.self_reference; + return this; } @@ -1078,10 +1240,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; } - // TODO: These are just (.back/.front) + .compose ?? - push_back = (ray: Ray) => { throw new NotImplementedError(); } - push_front = (ray: Ray) => { throw new NotImplementedError(); } - + push_back = (b: Ray) => this.last().compose(b); + push_front = (b: Ray) => this.first().compose(b); // [index: number]: Ray; @@ -1218,9 +1378,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // return []; // } // - includes(searchElement: Ray, fromIndex?: number): boolean { - return false; - } + // includes(searchElement: Ray, fromIndex?: number): boolean { + // return false; + // } // // toReversed(): Ray[] { // return []; diff --git a/src/@orbitmines/external/chyp/Chyp.spec.ts b/src/@orbitmines/external/chyp/Chyp.spec.ts index 453ef05..35e283f 100644 --- a/src/@orbitmines/external/chyp/Chyp.spec.ts +++ b/src/@orbitmines/external/chyp/Chyp.spec.ts @@ -4,7 +4,7 @@ import {Chyp} from "./Chyp"; describe("Chyp", () => { describe(".Graph", () => { test(".set_inputs", () => { - const graph = new Chyp.Graph() + const graph = Chyp.Graph.new() .set_inputs(Ray.vertex().o({ js: 'B' }).as_arbitrary()) .set_inputs(Ray.vertex().o({ js: 'A' }).as_arbitrary()); @@ -17,7 +17,7 @@ describe("Chyp", () => { }); describe(".Rule", () => { test(".name", () => { - let rule = new Chyp.Rule(); + let rule = Chyp.Rule.new(); rule.name = 'test'; expect(rule.name).toBe('test'); diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index 2a59472..3ee736d 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -23,6 +23,14 @@ export namespace Chyp { export type VData = Vertex; export class Vertex extends Ray { + static new = (): Vertex => { + return new Vertex(); + } + + protected constructor() { + super(); + } + // Vertex.in_edges = Ray.initial get in_edges(): Ray { return this.initial; } set in_edges(ray: Arbitrary) { this.initial = ray; } @@ -45,6 +53,25 @@ export namespace Chyp { export class Match extends Ray { + /** + * | <-- (vertex/edge)_map to (vertex/edge)_image + * _____|_____ + * / | \ + * Domain: [--|--][--|--][--|--] <-- Any of the matching structure on 'domain' is '_map'. + * | | | (is_total = true, if everything is on '_map') + * | | | + * Codomain: [--|--][--|--][--|--] <-- Any of the matching structure on 'codomain' is '_image'. + * | | | (is_surjective = true, if everything is on '_image') + */ + + static new = (): Match => { + return new Match(); + } + + protected constructor() { + super(); + } + // Match.domain = Ray.initial get domain(): Ray { return this.initial; } set domain(ray: Arbitrary) { this.initial = ray; } @@ -55,6 +82,14 @@ export namespace Chyp { export class Rule extends Ray { + static new = (): Rule => { + return new Rule(); + } + + protected constructor() { + super(); + } + // Rule.lhs = Ray.initial get lhs(): Ray { return this.initial; } set lhs(ray: Arbitrary) { this.initial = ray; } @@ -97,6 +132,14 @@ export namespace Chyp { export class Graph extends Ray { + static new = (): Graph => { + return new Graph(); + } + + protected constructor() { + super(); + } + // Graph.inputs = Ray.initial get inputs(): Ray { return this.initial; } set inputs(ray: Arbitrary) { this.initial = ray; } set_inputs = (ray: Arbitrary): Graph => { this.inputs = ray; return this; } diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts index 9797cbb..1ffa788 100644 --- a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts +++ b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts @@ -269,7 +269,6 @@ // * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. // */ // remove_vertex = (v = int, strict: boolean = false): Ray => { -// // TODO: destroy any reference of it (could just do this lazy) // // TODO: as delegation // // if (strict) { @@ -295,7 +294,6 @@ // * @param e Integer identifier of the edge to remove. // */ // remove_edge = (e = int): Ray => { -// // TODO: destroy any reference of it (could just do this lazy) // // in/out edges from all vertices // delete this.edata[e]; // } @@ -456,86 +454,86 @@ // // TODO: Add equivalence/reference on the inputs/output extremes. // } // - -// Merge = compose.. -// /** -// * Compose structures defined at .initial with those at .terminal, dropping the vertex. ; or if done non-ignorantly. Composing them on another level, ignoring to this vertex. TODO: Allow this freedom -// */ -// get merge(): Ray { -// // concat initial.a + initial.b, terminal.a + terminal.b -// // then: either destroy a/b, merge structure... etc.. -// // Chyp: destroy b -// -// // this.initial.equivalent(other.initial); -// // this.terminal.equivalent(other.terminal); -// -// /* -// -// vd = self.vertex_data(v) -// # print("merging %s <- %s" % (v, w)) -// -// # Where vertex `w` occurs as an edge target, replace it with `v` -// for e in self.in_edges(w): -// ed = self.edge_data(e) -// ed.t = [v if x == w else x for x in ed.t] -// vd.in_edges.add(e) -// -// # Where vertex `w` occurs as an edge source, replace it with `v` -// for e in self.out_edges(w): -// ed = self.edge_data(e) -// ed.s = [v if x == w else x for x in ed.s] -// vd.out_edges.add(e) -// -// # Wherever `w` occurs on the graph boundary, replace it with `v` -// self.set_inputs([v if x == w else x for x in self.inputs]) -// self.set_outputs([v if x == w else x for x in self.outputs]) -// -// # Remove references to `w` from the graph -// self.remove_vertex(w) -// -// */ -// throw new NotImplementedError(); -// } - - -// @alias('merge') ?? TODO -// static compose = Ray.___func(ref => { -// const { initial, terminal } = ref.self; -// -// return initial.___primitive_switch({ -// [RayType.VERTEX]: () => { -// const vertex = initial.self; -// -// // TODO; Implement as restrictive case for Chyp -// { -// // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) -// // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); // -// // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. -// // if (this.self.initial.is_equivalent(this.self.terminal)) -// // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output -// } +// // Merge = compose.. +// // /** +// // * Compose structures defined at .initial with those at .terminal, dropping the vertex. ; or if done non-ignorantly. Composing them on another level, ignoring to this vertex. TODO: Allow this freedom +// // */ +// // get merge(): Ray { +// // // concat initial.a + initial.b, terminal.a + terminal.b +// // // then: either destroy a/b, merge structure... etc.. +// // // Chyp: destroy b +// // +// // // this.initial.equivalent(other.initial); +// // // this.terminal.equivalent(other.terminal); +// // +// // /* +// // +// // vd = self.vertex_data(v) +// // # print("merging %s <- %s" % (v, w)) +// // +// // # Where vertex `w` occurs as an edge target, replace it with `v` +// // for e in self.in_edges(w): +// // ed = self.edge_data(e) +// // ed.t = [v if x == w else x for x in ed.t] +// // vd.in_edges.add(e) +// // +// // # Where vertex `w` occurs as an edge source, replace it with `v` +// // for e in self.out_edges(w): +// // ed = self.edge_data(e) +// // ed.s = [v if x == w else x for x in ed.s] +// // vd.out_edges.add(e) +// // +// // # Wherever `w` occurs on the graph boundary, replace it with `v` +// // self.set_inputs([v if x == w else x for x in self.inputs]) +// // self.set_outputs([v if x == w else x for x in self.outputs]) +// // +// // # Remove references to `w` from the graph +// // self.remove_vertex(w) +// // +// // */ +// // throw new NotImplementedError(); +// // } +// +// +// // @alias('merge') ?? TODO +// // static compose = Ray.___func(ref => { +// // const { initial, terminal } = ref.self; +// // +// // return initial.___primitive_switch({ +// // [RayType.VERTEX]: () => { +// // const vertex = initial.self; +// // +// // // TODO; Implement as restrictive case for Chyp +// // { +// // // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) +// // // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); +// // +// // // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. +// // // if (this.self.initial.is_equivalent(this.self.terminal)) +// // // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output +// // } +// // +// // /** +// // * A simple case of what we want to solve here. +// // * +// // * Initial Terminal +// // * ... ... +// // * [--| ] [ |--] +// // * [--| ] [ |--] +// // * [--| ] [ |--] +// // * [ |--] [--|--] [--| ] +// // * vertex +// // * +// // * And recursively (arbitrarily) match initial/terminal structures. +// // */ +// // +// // throw new NotImplementedError(); +// // } +// // }) +// // }); +// // compose = Ray.compose(this); // -// /** -// * A simple case of what we want to solve here. -// * -// * Initial Terminal -// * ... ... -// * [--| ] [ |--] -// * [--| ] [ |--] -// * [--| ] [ |--] -// * [ |--] [--|--] [--| ] -// * vertex -// * -// * And recursively (arbitrarily) match initial/terminal structures. -// */ -// -// throw new NotImplementedError(); -// } -// }) -// }); -// compose = Ray.compose(this); - // /** // * Sequentially compose this graph in-place with another. // * From 0397e8ac8527bd85daa36cb03585c278f7c8e895 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 18 Jan 2024 23:47:29 +0100 Subject: [PATCH 103/138] 2024/01/18 - More .any to a reference '.any.[]' pattern, introduce .all for applying functions based on arbitrary continuations --- src/@orbitmines/explorer/JS.spec.ts | 2 +- src/@orbitmines/explorer/Ray.spec.ts | 777 ++++++++++--------- src/@orbitmines/explorer/Ray.ts | 73 +- src/@orbitmines/external/chyp/Chyp.spec.ts | 6 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 8 +- 5 files changed, 469 insertions(+), 397 deletions(-) diff --git a/src/@orbitmines/explorer/JS.spec.ts b/src/@orbitmines/explorer/JS.spec.ts index 701eb1a..e6bc628 100644 --- a/src/@orbitmines/explorer/JS.spec.ts +++ b/src/@orbitmines/explorer/JS.spec.ts @@ -6,7 +6,7 @@ describe("JS", () => { a: 'b', position: [0, 1, 2], func: () => 'c' - }); + }).as_reference(); expect(ray.any.a).toBe('b'); expect(ray.any.test).toBe(undefined); diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index ac6b209..56026dd 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -16,8 +16,8 @@ describe("Ray", () => { const b = Ray.vertex().o({ js: 'B'}).as_reference(); // TODO What about method(a)(b)(c)... :thinking: - expect(method(a)(b).initial.self.any.js).toBe('A'); - expect(method(a)(b).terminal.self.any.js).toBe('B'); + expect(method(a)(b).initial.any.js).toBe('A'); + expect(method(a)(b).terminal.any.js).toBe('B'); expect(method(a)(b).type).toBe(RayType.VERTEX); }); test("[A, B, C].copy", () => { @@ -39,7 +39,7 @@ describe("Ray", () => { expect(A_vertex.is_none()).toBe(false); expect(A_ref.follow().is_none()).toBe(false); expect(A_ref.follow(Ray.directions.previous).is_none()).toBe(false); - expect(A_vertex.any.js).toBe('A'); + expect(A_ref.any.js).toBe('A'); expect(A_ref.is_none()).toBe(false); A_ref.delete(); @@ -50,7 +50,7 @@ describe("Ray", () => { expect(A_vertex.any.js).toBe(undefined); expect(A_ref.is_none()).toBe(true); }); - test("[A, B, C].___next()", () => { + test("[A, B, C, D, E].all().js", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); @@ -59,7 +59,36 @@ describe("Ray", () => { A.compose(B).compose(C).compose(D).compose(E); - expect([...A.___next()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E']); + expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); + }); + test("[A, B, C, D, E].all() ; -= / +=", () => { + const A = Ray.vertex().o({ js: 'A', value: 0 }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B', value: 1 }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C', value: 2 }).as_reference().o({ js: 'C.#' }); + const D = Ray.vertex().o({ js: 'D', value: 3 }).as_reference().o({ js: 'D.#' }); + const E = Ray.vertex().o({ js: 'E', value: 4 }).as_reference().o({ js: 'E.#' }); + + A.compose(B).compose(C).compose(D).compose(E); + + A.all().value = (value: number) => value - 3; + expect([...A.all().value]).toEqual([-3, -2, -1, 0, 1]); + + C.all().value = (value: number) => value + 10; + expect([...A.all().value]).toEqual([-3, -2, 9, 10, 11]); + + D.all(Ray.directions.previous).value = (value: number) => value - 50; + expect([...A.all().value]).toEqual([-53, -52, -41, -40, 11]); + }); + test("[A, B, C, D, E].___next()", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); + const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); + + A.compose(B).compose(C).compose(D).compose(E); + + expect([...A.___next()].map(ref => ref.any.js)).toEqual(['A', 'B', 'C', 'D', 'E']); }); test("[A, B, C].___traverse()", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -71,7 +100,7 @@ describe("Ray", () => { A.compose(B).compose(C).compose(D).compose(E); expect([...A.___traverse()].map(pointer => - [pointer.initial.type, pointer.terminal.type, pointer.initial.self.any.js] + [pointer.initial.type, pointer.terminal.type, pointer.initial.any.js] )).toEqual([ [RayType.VERTEX, RayType.TERMINAL, 'A'], [RayType.TERMINAL, RayType.INITIAL, undefined], @@ -108,7 +137,7 @@ describe("Ray", () => { * [--A--] [--B--] [--C--] */ - expect(pointer.initial.self.any.js).toBe('A'); + expect(pointer.initial.any.js).toBe('A'); expect(pointer.initial.type).toBe(RayType.VERTEX); expect(pointer.terminal.type).toBe(RayType.TERMINAL); @@ -132,7 +161,7 @@ describe("Ray", () => { */ expect(pointer.initial.type).toBe(RayType.INITIAL); expect(pointer.terminal.type).toBe(RayType.VERTEX); - expect(pointer.terminal.self.any.js).toBe('B'); + expect(pointer.terminal.any.js).toBe('B'); pointer = pointer.step(); @@ -163,7 +192,7 @@ describe("Ray", () => { */ expect(pointer.initial.type).toBe(RayType.INITIAL); expect(pointer.terminal.type).toBe(RayType.VERTEX); - expect(pointer.terminal.self.any.js).toBe('C'); + expect(pointer.terminal.any.js).toBe('C'); pointer = pointer.step(); @@ -200,7 +229,7 @@ describe("Ray", () => { terminal: () => Ray.directions.previous(C), }); - expect(pointer.initial.self.any.js).toBe('C'); + expect(pointer.initial.any.js).toBe('C'); expect(pointer.initial.type).toBe(RayType.VERTEX); expect(pointer.terminal.type).toBe(RayType.INITIAL); @@ -214,7 +243,7 @@ describe("Ray", () => { expect(pointer.initial.type).toBe(RayType.TERMINAL); expect(pointer.terminal.type).toBe(RayType.VERTEX); - expect(pointer.terminal.self.any.js).toBe('B'); + expect(pointer.terminal.any.js).toBe('B'); pointer = pointer.step(); @@ -230,7 +259,7 @@ describe("Ray", () => { expect(pointer.initial.type).toBe(RayType.TERMINAL); expect(pointer.terminal.type).toBe(RayType.VERTEX); - expect(pointer.terminal.self.any.js).toBe('A'); + expect(pointer.terminal.any.js).toBe('A'); pointer = pointer.step(); @@ -278,13 +307,13 @@ describe("Ray", () => { A.compose(B).compose(C); - expect(A.first().self.any.js).toBe('A'); - expect(B.first().self.any.js).toBe('A'); - expect(C.first().self.any.js).toBe('A'); + expect(A.first().any.js).toBe('A'); + expect(B.first().any.js).toBe('A'); + expect(C.first().any.js).toBe('A'); - expect(A.last().self.any.js).toBe('C'); - expect(B.last().self.any.js).toBe('C'); - expect(C.last().self.any.js).toBe('C'); + expect(A.last().any.js).toBe('C'); + expect(B.last().any.js).toBe('C'); + expect(C.last().any.js).toBe('C'); }); test("[A, B, C][.at()]", () => { const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); @@ -296,9 +325,9 @@ describe("Ray", () => { expect(A.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); expect(A.at(-100).is_none()).toBe(true); expect(A.at(-1).is_none()).toBe(true); - expect(A.at(0).self.any.js).toBe('A'); - expect(A.at(1).self.any.js).toBe('B'); - expect(A.at(2).self.any.js).toBe('C'); + expect(A.at(0).any.js).toBe('A'); + expect(A.at(1).any.js).toBe('B'); + expect(A.at(2).any.js).toBe('C'); expect(A.at(3).is_none()).toBe(true); expect(A.at(100).is_none()).toBe(true); expect(A.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); @@ -306,9 +335,9 @@ describe("Ray", () => { expect(B.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); expect(B.at(-100).is_none()).toBe(true); expect(B.at(-2).is_none()).toBe(true); - expect(B.at(-1).self.any.js).toBe('A'); - expect(B.at(0).self.any.js).toBe('B'); - expect(B.at(1).self.any.js).toBe('C'); + expect(B.at(-1).any.js).toBe('A'); + expect(B.at(0).any.js).toBe('B'); + expect(B.at(1).any.js).toBe('C'); expect(B.at(2).is_none()).toBe(true); expect(B.at(100).is_none()).toBe(true); expect(B.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); @@ -316,9 +345,9 @@ describe("Ray", () => { expect(C.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); expect(C.at(-100).is_none()).toBe(true); expect(C.at(-3).is_none()).toBe(true); - expect(C.at(-2).self.any.js).toBe('A'); - expect(C.at(-1).self.any.js).toBe('B'); - expect(C.at(0).self.any.js).toBe('C'); + expect(C.at(-2).any.js).toBe('A'); + expect(C.at(-1).any.js).toBe('B'); + expect(C.at(0).any.js).toBe('C'); expect(C.at(1).is_none()).toBe(true); expect(C.at(100).is_none()).toBe(true); expect(C.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); @@ -383,16 +412,16 @@ describe("Ray", () => { expect(A.next().type).toBe(RayType.VERTEX); // expect(current.next().any.js).toBe('B.#'); TODO, maybe the ref?? - expect(A.next().self.any.js).toBe('B'); + expect(A.next().any.js).toBe('B'); expect(A.next().next().type).toBe(RayType.VERTEX); - expect(A.next().next().self.any.js).toBe('C'); + expect(A.next().next().any.js).toBe('C'); - expect(A.next().previous().self.any.js).toBe('A'); - expect(A.next().next().previous().self.any.js).toBe('B'); - expect(A.next().next().previous().previous().self.any.js).toBe('A'); - expect(A.next().previous().next().next().previous().self.any.js).toBe('B'); - expect(A.next().previous().next().next().previous().next().self.any.js).toBe('C'); + expect(A.next().previous().any.js).toBe('A'); + expect(A.next().next().previous().any.js).toBe('B'); + expect(A.next().next().previous().previous().any.js).toBe('A'); + expect(A.next().previous().next().next().previous().any.js).toBe('B'); + expect(A.next().previous().next().next().previous().next().any.js).toBe('C'); }); test("[A, B, C], [X, Y, Z] ; C.compose(X)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -408,10 +437,10 @@ describe("Ray", () => { C.compose(X); - expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); - expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); - expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X', 'C', 'B', 'A']); - expect([...X].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + expect([...A.all().js]).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); + expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); + expect([...X.all(Ray.directions.previous).js]).toEqual(['X', 'C', 'B', 'A']); + expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); }); // test("[A, B, C], [X, Y, Z] ; B.compose(X)", () => { // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -427,10 +456,10 @@ describe("Ray", () => { // // B.compose(X); // - // // expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); - // // expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); - // // expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X', 'C', 'B', 'A']); - // // expect([...X].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); + // // expect([...A.all().js]).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); + // // expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); + // // expect([...X.all(Ray.directions.previous).js]).toEqual(['X', 'C', 'B', 'A']); + // // expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); // }); test("[A, [X, Y, Z].initial, B, C][.next(), .previous()]", () => { // /** @@ -520,14 +549,14 @@ describe("Ray", () => { // expect(B.type).toBe(RayType.VERTEX); // // expect(A.is_none()).toBe(true); + // expect(A.any.js).toBe('A'); // expect(A.self.any.js).toBe('A'); // expect(A.self.self.any.js).toBe('A'); - // expect(A.self.self.self.any.js).toBe('A'); // // expect(B.is_none()).toBe(true); + // expect(B.any.js).toBe('B'); // expect(B.self.any.js).toBe('B'); // expect(B.self.self.any.js).toBe('B'); - // expect(B.self.self.self.any.js).toBe('B'); // // A.equivalent(B); // @@ -535,14 +564,14 @@ describe("Ray", () => { // expect(B.type).toBe(RayType.REFERENCE); // Turns B into a reference to A. // // expect(A.is_none()).toBe(false); - // expect(A.self.any.js).toBe('A'); - // expect(A.self.self.any.js).toBe('B'); - // expect(A.self.self.self.any.js).toBe('A'); + // expect(A.any.js).toBe('A'); + // expect(A.self.any.js).toBe('B'); + // expect(A.self.self.any.js).toBe('A'); // // expect(B.is_none()).toBe(false); - // expect(B.self.any.js).toBe('B'); - // expect(B.self.self.any.js).toBe('A'); - // expect(B.self.self.self.any.js).toBe('B'); + // expect(B.any.js).toBe('B'); + // expect(B.self.any.js).toBe('A'); + // expect(B.self.self.any.js).toBe('B'); // }); test(".vertex.#.equivalent(.vertex.#)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -550,8 +579,8 @@ describe("Ray", () => { expect(A.type).toBe(RayType.VERTEX); expect(B.type).toBe(RayType.VERTEX); - expect(A.any.js).toBe('A.#'); - expect(B.any.js).toBe('B.#'); + expect(A.as_reference().any.js).toBe('A.#'); + expect(B.as_reference().any.js).toBe('B.#'); expect(A.is_none()).toBe(false); expect(A.dereference.is_none()).toBe(true); @@ -564,20 +593,20 @@ describe("Ray", () => { expect(A.type).toBe(RayType.VERTEX); expect(A.self.type).toBe(RayType.VERTEX); expect(A.is_none()).toBe(false); - expect(A.self.any.js).toBe('A'); - expect(A.self.self.any.js).toBe('___as_vertex'); - expect(A.self.self.self.any.js).toBe('A'); - expect([...A.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); - expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect(A.any.js).toBe('A'); + expect(A.self.any.js).toBe('___as_vertex'); + expect(A.self.self.any.js).toBe('A'); + expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B']); + expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); expect(B.type).toBe(RayType.VERTEX); expect(B.self.type).toBe(RayType.VERTEX); expect(B.is_none()).toBe(false); - expect(B.self.any.js).toBe('B'); - expect(B.self.self.any.js).toBe('___as_vertex'); - expect(B.self.self.self.any.js).toBe('B'); - expect([...B.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B']); - expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect(B.any.js).toBe('B'); + expect(B.self.any.js).toBe('___as_vertex'); + expect(B.self.self.any.js).toBe('B'); + expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B']); + expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); }); test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y).equiv(J).equiv(R)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -602,33 +631,33 @@ describe("Ray", () => { Q.compose(R).compose(S); // BEFORE .equivalent - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); - expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); - expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); - expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); - expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); - expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); - expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); - - expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); - expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); - expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); - expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); - expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); - expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); - - expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); - expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); - expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); - expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); - expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); - expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + expect([...A.all().js]).toEqual(['A', 'B', 'C']); + expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); + expect([...B.all().js]).toEqual(['B', 'C']); + expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); + expect([...C.all().js]).toEqual(['C']); + expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); + + expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); + expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); + expect([...Y.all().js]).toEqual(['Y', 'Z']); + expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); + expect([...Z.all().js]).toEqual(['Z']); + expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); + + expect([...I.all().js]).toEqual(['I', 'J', 'K']); + expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); + expect([...J.all().js]).toEqual(['J', 'K']); + expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); + expect([...K.all().js]).toEqual(['K']); + expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); + + expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); + expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); + expect([...R.all().js]).toEqual(['R', 'S']); + expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); + expect([...S.all().js]).toEqual(['S']); + expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); /** * Drawing an equivalence between `B -> Y -> J -> R`. (Doesn't need to hold in some more abstract sense, it's just a line) @@ -648,66 +677,66 @@ describe("Ray", () => { // TODO: Still one bug, J.# ->, makes the equiv(R) a parallel composition, so something is TERMINAL/INITIAL -> VERTEX // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); - expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); - expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); - expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); - expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); - expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); - expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); - - expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); - expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); - expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); - expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); - expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); - expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); - - expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); - expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); - expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); - expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); - expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); - expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + expect([...A.all().js]).toEqual(['A', 'B', 'C']); + expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); + expect([...B.all().js]).toEqual(['B', 'C']); + expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); + expect([...C.all().js]).toEqual(['C']); + expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); + + expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); + expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); + expect([...Y.all().js]).toEqual(['Y', 'Z']); + expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); + expect([...Z.all().js]).toEqual(['Z']); + expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); + + expect([...I.all().js]).toEqual(['I', 'J', 'K']); + expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); + expect([...J.all().js]).toEqual(['J', 'K']); + expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); + expect([...K.all().js]).toEqual(['K']); + expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); + + expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); + expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); + expect([...R.all().js]).toEqual(['R', 'S']); + expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); + expect([...S.all().js]).toEqual(['S']); + expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); // But they should be connected through their .vertex/.self: expect(B.dereference.is_none()).toBe(false); expect(B.dereference.type).toBe(RayType.VERTEX); expect(B.dereference.self).not.toBe(B.self); - expect(B.dereference.self.self.any.js).toBe('B'); - expect(B.dereference.self.any.js).toBe('___as_vertex'); - expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B']); - expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); + expect(B.dereference.self.any.js).toBe('B'); + expect(B.dereference.any.js).toBe('___as_vertex'); + expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B']); + expect([...B.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); expect(Y.dereference.is_none()).toBe(false); expect(Y.dereference.type).toBe(RayType.VERTEX); expect(Y.dereference.self).not.toBe(Y.self); - expect(Y.dereference.self.self.any.js).toBe('Y'); - expect(Y.dereference.self.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); + expect(Y.dereference.self.any.js).toBe('Y'); + expect(Y.dereference.any.js).toBe('___as_vertex'); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'B']); + expect([...Y.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'J', 'R']); expect(J.dereference.is_none()).toBe(false); expect(J.dereference.type).toBe(RayType.VERTEX); expect(J.dereference.self).not.toBe(J.self); - expect(J.dereference.self.self.any.js).toBe('J'); - expect(J.dereference.self.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); - expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); + expect(J.dereference.self.any.js).toBe('J'); + expect(J.dereference.any.js).toBe('___as_vertex'); + expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'Y', 'B']); + expect([...J.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'R']); expect(R.dereference.is_none()).toBe(false); expect(R.dereference.type).toBe(RayType.VERTEX); expect(R.dereference.self).not.toBe(R.self); - expect(R.dereference.self.self.any.js).toBe('R'); - expect(R.dereference.self.any.js).toBe('___as_vertex'); - expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); - expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R']); + expect(R.dereference.self.any.js).toBe('R'); + expect(R.dereference.any.js).toBe('___as_vertex'); + expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); + expect([...R.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['R']); }); test("([ABC], [XYZ], [IJK]]) ; B.equiv(Y).equiv(J)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -727,26 +756,26 @@ describe("Ray", () => { I.compose(J).compose(K); // BEFORE .equivalent - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); - expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); - expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); - expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); - expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); - expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); - expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); - - expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); - expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); - expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); - expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); - expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); - expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + expect([...A.all().js]).toEqual(['A', 'B', 'C']); + expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); + expect([...B.all().js]).toEqual(['B', 'C']); + expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); + expect([...C.all().js]).toEqual(['C']); + expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); + + expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); + expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); + expect([...Y.all().js]).toEqual(['Y', 'Z']); + expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); + expect([...Z.all().js]).toEqual(['Z']); + expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); + + expect([...I.all().js]).toEqual(['I', 'J', 'K']); + expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); + expect([...J.all().js]).toEqual(['J', 'K']); + expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); + expect([...K.all().js]).toEqual(['K']); + expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); /** * Drawing an equivalence between `B -> Y -> J`. (Doesn't need to hold in some more abstract sense, it's just a line) @@ -761,51 +790,51 @@ describe("Ray", () => { B.equivalent(Y).equivalent(J); // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); - expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); - expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); - expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); - expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); - expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); - expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); - - expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); - expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); - expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); - expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); - expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); - expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); + expect([...A.all().js]).toEqual(['A', 'B', 'C']); + expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); + expect([...B.all().js]).toEqual(['B', 'C']); + expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); + expect([...C.all().js]).toEqual(['C']); + expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); + + expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); + expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); + expect([...Y.all().js]).toEqual(['Y', 'Z']); + expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); + expect([...Z.all().js]).toEqual(['Z']); + expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); + + expect([...I.all().js]).toEqual(['I', 'J', 'K']); + expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); + expect([...J.all().js]).toEqual(['J', 'K']); + expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); + expect([...K.all().js]).toEqual(['K']); + expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); // But they should be connected through their .vertex/.self: expect(B.dereference.is_none()).toBe(false); expect(B.dereference.type).toBe(RayType.VERTEX); expect(B.dereference.self).not.toBe(B.self); - expect(B.dereference.self.self.any.js).toBe('B'); - expect(B.dereference.self.any.js).toBe('___as_vertex'); + expect(B.dereference.self.any.js).toBe('B'); + expect(B.dereference.any.js).toBe('___as_vertex'); expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(1); - expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J']); + expect([...B.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'Y', 'J']); expect(Y.dereference.is_none()).toBe(false); expect(Y.dereference.type).toBe(RayType.VERTEX); expect(Y.dereference.self).not.toBe(Y.self); - expect(Y.dereference.self.self.any.js).toBe('Y'); - expect(Y.dereference.self.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J']); + expect(Y.dereference.self.any.js).toBe('Y'); + expect(Y.dereference.any.js).toBe('___as_vertex'); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'B']); + expect([...Y.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'J']); expect(J.dereference.is_none()).toBe(false); expect(J.dereference.type).toBe(RayType.VERTEX); expect(J.dereference.self).not.toBe(J.self); - expect(J.dereference.self.self.any.js).toBe('J'); - expect(J.dereference.self.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); - expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J']); + expect(J.dereference.self.any.js).toBe('J'); + expect(J.dereference.any.js).toBe('___as_vertex'); + expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'Y', 'B']); + expect([...J.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['J']); }); test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y) ; J.equiv(J) ; Y.equiv(J)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -830,33 +859,33 @@ describe("Ray", () => { Q.compose(R).compose(S); // BEFORE .equivalent - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); - expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); - expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); - expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); - expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); - expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); - expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); - - expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); - expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); - expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); - expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); - expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); - expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); - - expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); - expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); - expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); - expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); - expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); - expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + expect([...A.all().js]).toEqual(['A', 'B', 'C']); + expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); + expect([...B.all().js]).toEqual(['B', 'C']); + expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); + expect([...C.all().js]).toEqual(['C']); + expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); + + expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); + expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); + expect([...Y.all().js]).toEqual(['Y', 'Z']); + expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); + expect([...Z.all().js]).toEqual(['Z']); + expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); + + expect([...I.all().js]).toEqual(['I', 'J', 'K']); + expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); + expect([...J.all().js]).toEqual(['J', 'K']); + expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); + expect([...K.all().js]).toEqual(['K']); + expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); + + expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); + expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); + expect([...R.all().js]).toEqual(['R', 'S']); + expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); + expect([...S.all().js]).toEqual(['S']); + expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); /** * Drawing an equivalence between `B -> Y -> J -> R`. (Doesn't need to hold in some more abstract sense, it's just a line) @@ -875,66 +904,66 @@ describe("Ray", () => { Y.equivalent(J); // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - expect([...B.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect([...B.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - expect([...C.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); - expect([...C.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect([...X.traverse()].map(ref => ref.self.any.js)).toEqual(['X', 'Y', 'Z']); - expect([...X.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['X']); - expect([...Y.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'Z']); - expect([...Y.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'X']); - expect([...Z.traverse()].map(ref => ref.self.any.js)).toEqual(['Z']); - expect([...Z.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Z', 'Y', 'X']); - - expect([...I.traverse()].map(ref => ref.self.any.js)).toEqual(['I', 'J', 'K']); - expect([...I.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['I']); - expect([...J.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'K']); - expect([...J.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'I']); - expect([...K.traverse()].map(ref => ref.self.any.js)).toEqual(['K']); - expect([...K.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['K', 'J', 'I']); - - expect([...Q.traverse()].map(ref => ref.self.any.js)).toEqual(['Q', 'R', 'S']); - expect([...Q.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Q']); - expect([...R.traverse()].map(ref => ref.self.any.js)).toEqual(['R', 'S']); - expect([...R.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'Q']); - expect([...S.traverse()].map(ref => ref.self.any.js)).toEqual(['S']); - expect([...S.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['S', 'R', 'Q']); + expect([...A.all().js]).toEqual(['A', 'B', 'C']); + expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); + expect([...B.all().js]).toEqual(['B', 'C']); + expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); + expect([...C.all().js]).toEqual(['C']); + expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); + + expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); + expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); + expect([...Y.all().js]).toEqual(['Y', 'Z']); + expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); + expect([...Z.all().js]).toEqual(['Z']); + expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); + + expect([...I.all().js]).toEqual(['I', 'J', 'K']); + expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); + expect([...J.all().js]).toEqual(['J', 'K']); + expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); + expect([...K.all().js]).toEqual(['K']); + expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); + + expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); + expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); + expect([...R.all().js]).toEqual(['R', 'S']); + expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); + expect([...S.all().js]).toEqual(['S']); + expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); // But they should be connected through their .vertex/.self: expect(B.dereference.is_none()).toBe(false); expect(B.dereference.type).toBe(RayType.VERTEX); expect(B.dereference.self).not.toBe(B.self); - expect(B.dereference.self.self.any.js).toBe('B'); - expect(B.dereference.self.any.js).toBe('___as_vertex'); + expect(B.dereference.self.any.js).toBe('B'); + expect(B.dereference.any.js).toBe('___as_vertex'); expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(1); - expect([...B.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); + expect([...B.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); expect(Y.dereference.is_none()).toBe(false); expect(Y.dereference.type).toBe(RayType.VERTEX); expect(Y.dereference.self).not.toBe(Y.self); - expect(Y.dereference.self.self.any.js).toBe('Y'); - expect(Y.dereference.self.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['Y', 'J', 'R']); + expect(Y.dereference.self.any.js).toBe('Y'); + expect(Y.dereference.any.js).toBe('___as_vertex'); + expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'B']); + expect([...Y.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'J', 'R']); expect(J.dereference.is_none()).toBe(false); expect(J.dereference.type).toBe(RayType.VERTEX); expect(J.dereference.self).not.toBe(J.self); - expect(J.dereference.self.self.any.js).toBe('J'); - expect(J.dereference.self.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['J', 'Y', 'B']); - expect([...J.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['J', 'R']); + expect(J.dereference.self.any.js).toBe('J'); + expect(J.dereference.any.js).toBe('___as_vertex'); + expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'Y', 'B']); + expect([...J.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'R']); expect(R.dereference.is_none()).toBe(false); expect(R.dereference.type).toBe(RayType.VERTEX); expect(R.dereference.self).not.toBe(R.self); - expect(R.dereference.self.self.any.js).toBe('R'); - expect(R.dereference.self.any.js).toBe('___as_vertex'); - expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); - expect([...R.dereference.traverse()].map(ref => ref.self.self.any.js)).toEqual(['R']); + expect(R.dereference.self.any.js).toBe('R'); + expect(R.dereference.any.js).toBe('___as_vertex'); + expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); + expect([...R.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['R']); }); // test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -946,17 +975,17 @@ describe("Ray", () => { // // expect(terminal.type).toBe(RayType.TERMINAL); // - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); + // expect([...terminal.follow(Ray.directions.previous).all(Ray.directions.previous).js]).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); // // /** // * These should keep looping... // * TODO: Better test helper for this // */ - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['A', 'B']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['A', 'B']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); // }); // test("(A:vertex.# = B:vertex.#) ; B.as_terminal", () => { // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -968,17 +997,17 @@ describe("Ray", () => { // // expect(terminal.type).toBe(RayType.TERMINAL); // - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + // expect([...terminal.follow(Ray.directions.previous).all(Ray.directions.previous).js]).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); // // /** // * These should keep looping... // * TODO: Better test helper for this // */ - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['B', 'A']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['B', 'A']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); // }); // test("(A:vertex.# = B:vertex.#) ; A.as_initial", () => { // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -990,17 +1019,17 @@ describe("Ray", () => { // // expect(initial.type).toBe(RayType.INITIAL); // - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['A', 'B']); + // expect([...initial.follow().all(Ray.directions.next).js]).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); // // /** // * These should keep looping... // * TODO: Better test helper for this // */ - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['A', 'B']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['A', 'B']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); // }); // test("(A:vertex.# = B:vertex.#) ; B.as_initial", () => { // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -1012,17 +1041,17 @@ describe("Ray", () => { // // expect(initial.type).toBe(RayType.INITIAL); // - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + // expect([...initial.follow().all(Ray.directions.next).js]).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); // // /** // * These should keep looping... // * TODO: Better test helper for this // */ - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['B', 'A']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.self.any.js)).toEqual(['B', 'A']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); + // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); // }); test("A.equiv(B).equiv(C)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -1035,29 +1064,29 @@ describe("Ray", () => { expect(A.self.type).toBe(RayType.VERTEX); expect(A.is_none()).toBe(false); - expect(A.self.any.js).toBe('A'); - expect(A.self.self.any.js).toBe('___as_vertex'); - expect(A.self.self.self.any.js).toBe('A'); - expect([...A.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect(A.any.js).toBe('A'); + expect(A.self.any.js).toBe('___as_vertex'); + expect(A.self.self.any.js).toBe('A'); + expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); expect(B.type).toBe(RayType.VERTEX); expect(B.self.type).toBe(RayType.VERTEX); expect(B.is_none()).toBe(false); - expect(B.self.any.js).toBe('B'); - expect(B.self.self.any.js).toBe('___as_vertex'); - expect(B.self.self.self.any.js).toBe('B'); - expect([...B.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C']); - expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect(B.any.js).toBe('B'); + expect(B.self.any.js).toBe('___as_vertex'); + expect(B.self.self.any.js).toBe('B'); + expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); + expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); expect(C.type).toBe(RayType.VERTEX); expect(C.self.type).toBe(RayType.VERTEX); expect(C.is_none()).toBe(false); - expect(C.self.any.js).toBe('C'); - expect(C.self.self.any.js).toBe('___as_vertex'); - expect(C.self.self.self.any.js).toBe('C'); - expect([...C.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C']); - expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); + expect(C.any.js).toBe('C'); + expect(C.self.any.js).toBe('___as_vertex'); + expect(C.self.self.any.js).toBe('C'); + expect([...C.self.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); + expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); }); test("A.equiv(B).equiv(C).equiv(D).equiv(E).equiv(F) ; different order", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -1074,56 +1103,56 @@ describe("Ray", () => { expect(A.type).toBe(RayType.VERTEX); expect(A.self.type).toBe(RayType.VERTEX); expect(A.is_none()).toBe(false); - expect(A.self.any.js).toBe('A'); - expect(A.self.self.any.js).toBe('___as_vertex'); - expect(A.self.self.self.any.js).toBe('A'); - expect([...A.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); - expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect(A.any.js).toBe('A'); + expect(A.self.any.js).toBe('___as_vertex'); + expect(A.self.self.any.js).toBe('A'); + expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); + expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); expect(B.type).toBe(RayType.VERTEX); expect(B.self.type).toBe(RayType.VERTEX); expect(B.is_none()).toBe(false); - expect(B.self.any.js).toBe('B'); - expect(B.self.self.any.js).toBe('___as_vertex'); - expect(B.self.self.self.any.js).toBe('B'); - expect([...B.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); - expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect(B.any.js).toBe('B'); + expect(B.self.any.js).toBe('___as_vertex'); + expect(B.self.self.any.js).toBe('B'); + expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); + expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); expect(C.type).toBe(RayType.VERTEX); expect(C.self.type).toBe(RayType.VERTEX); expect(C.is_none()).toBe(false); - expect(C.self.any.js).toBe('C'); - expect(C.self.self.any.js).toBe('___as_vertex'); - expect(C.self.self.self.any.js).toBe('C'); - expect([...C.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C', 'D', 'E', 'F']); - expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); + expect(C.any.js).toBe('C'); + expect(C.self.any.js).toBe('___as_vertex'); + expect(C.self.self.any.js).toBe('C'); + expect([...C.self.traverse()].map(ref => ref.self.any.js)).toEqual(['C', 'D', 'E', 'F']); + expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); expect(D.type).toBe(RayType.VERTEX); expect(D.self.type).toBe(RayType.VERTEX); expect(D.is_none()).toBe(false); - expect(D.self.any.js).toBe('D'); - expect(D.self.self.any.js).toBe('___as_vertex'); - expect(D.self.self.self.any.js).toBe('D'); - expect([...D.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['D', 'E', 'F']); - expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['D', 'C', 'B', 'A']); + expect(D.any.js).toBe('D'); + expect(D.self.any.js).toBe('___as_vertex'); + expect(D.self.self.any.js).toBe('D'); + expect([...D.self.traverse()].map(ref => ref.self.any.js)).toEqual(['D', 'E', 'F']); + expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['D', 'C', 'B', 'A']); expect(E.type).toBe(RayType.VERTEX); expect(E.self.type).toBe(RayType.VERTEX); expect(E.is_none()).toBe(false); - expect(E.self.any.js).toBe('E'); - expect(E.self.self.any.js).toBe('___as_vertex'); - expect(E.self.self.self.any.js).toBe('E'); - expect([...E.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['E', 'F']); - expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); + expect(E.any.js).toBe('E'); + expect(E.self.any.js).toBe('___as_vertex'); + expect(E.self.self.any.js).toBe('E'); + expect([...E.self.traverse()].map(ref => ref.self.any.js)).toEqual(['E', 'F']); + expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); expect(F.type).toBe(RayType.VERTEX); expect(F.self.type).toBe(RayType.VERTEX); expect(F.is_none()).toBe(false); - expect(F.self.any.js).toBe('F'); - expect(F.self.self.any.js).toBe('___as_vertex'); - expect(F.self.self.self.any.js).toBe('F'); - expect([...F.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['F']); - expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); + expect(F.any.js).toBe('F'); + expect(F.self.any.js).toBe('___as_vertex'); + expect(F.self.self.any.js).toBe('F'); + expect([...F.self.traverse()].map(ref => ref.self.any.js)).toEqual(['F']); + expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); }); test("A.equiv(B).equiv(C).equiv(D).equiv(E).equiv(F)", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); @@ -1154,56 +1183,56 @@ describe("Ray", () => { expect(A.self.type).toBe(RayType.VERTEX); expect(A.is_none()).toBe(false); - expect(A.self.any.js).toBe('A'); - expect(A.self.self.any.js).toBe('___as_vertex'); - expect(A.self.self.self.any.js).toBe('A'); - expect([...A.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); - expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['A']); + expect(A.any.js).toBe('A'); + expect(A.self.any.js).toBe('___as_vertex'); + expect(A.self.self.any.js).toBe('A'); + expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); + expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); expect(B.type).toBe(RayType.VERTEX); expect(B.self.type).toBe(RayType.VERTEX); expect(B.is_none()).toBe(false); - expect(B.self.any.js).toBe('B'); - expect(B.self.self.any.js).toBe('___as_vertex'); - expect(B.self.self.self.any.js).toBe('B'); - expect([...B.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); - expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['B', 'A']); + expect(B.any.js).toBe('B'); + expect(B.self.any.js).toBe('___as_vertex'); + expect(B.self.self.any.js).toBe('B'); + expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); + expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); expect(C.type).toBe(RayType.VERTEX); expect(C.self.type).toBe(RayType.VERTEX); expect(C.is_none()).toBe(false); - expect(C.self.any.js).toBe('C'); - expect(C.self.self.any.js).toBe('___as_vertex'); - expect(C.self.self.self.any.js).toBe('C'); - expect([...C.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['C', 'D', 'E', 'F']); - expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['C', 'B', 'A']); + expect(C.any.js).toBe('C'); + expect(C.self.any.js).toBe('___as_vertex'); + expect(C.self.self.any.js).toBe('C'); + expect([...C.self.traverse()].map(ref => ref.self.any.js)).toEqual(['C', 'D', 'E', 'F']); + expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); expect(D.type).toBe(RayType.VERTEX); expect(D.self.type).toBe(RayType.VERTEX); expect(D.is_none()).toBe(false); - expect(D.self.any.js).toBe('D'); - expect(D.self.self.any.js).toBe('___as_vertex'); - expect(D.self.self.self.any.js).toBe('D'); - expect([...D.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['D', 'E', 'F']); - expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['D', 'C', 'B', 'A']); + expect(D.any.js).toBe('D'); + expect(D.self.any.js).toBe('___as_vertex'); + expect(D.self.self.any.js).toBe('D'); + expect([...D.self.traverse()].map(ref => ref.self.any.js)).toEqual(['D', 'E', 'F']); + expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['D', 'C', 'B', 'A']); expect(E.type).toBe(RayType.VERTEX); expect(E.self.type).toBe(RayType.VERTEX); expect(E.is_none()).toBe(false); - expect(E.self.any.js).toBe('E'); - expect(E.self.self.any.js).toBe('___as_vertex'); - expect(E.self.self.self.any.js).toBe('E'); - expect([...E.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['E', 'F']); - expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); + expect(E.any.js).toBe('E'); + expect(E.self.any.js).toBe('___as_vertex'); + expect(E.self.self.any.js).toBe('E'); + expect([...E.self.traverse()].map(ref => ref.self.any.js)).toEqual(['E', 'F']); + expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); expect(F.type).toBe(RayType.VERTEX); expect(F.self.type).toBe(RayType.VERTEX); expect(F.is_none()).toBe(false); - expect(F.self.any.js).toBe('F'); - expect(F.self.self.any.js).toBe('___as_vertex'); - expect(F.self.self.self.any.js).toBe('F'); - expect([...F.self.traverse()].map(ref => ref.self.self.any.js)).toEqual(['F']); - expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); + expect(F.any.js).toBe('F'); + expect(F.self.any.js).toBe('___as_vertex'); + expect(F.self.self.any.js).toBe('F'); + expect([...F.self.traverse()].map(ref => ref.self.any.js)).toEqual(['F']); + expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); }); // test(".None.#.equivalent(.vertex.#)", () => { // const A = Ray.None().as_reference(); @@ -1220,13 +1249,13 @@ describe("Ray", () => { A.compose(B).compose(C); - expect(A.as_array().map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect(B.as_array().map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect(C.as_array().map(ref => ref.self.any.js)).toEqual(['C']); + expect(A.as_array().map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); + expect(B.as_array().map(ref => ref.any.js)).toEqual(['B', 'C']); + expect(C.as_array().map(ref => ref.any.js)).toEqual(['C']); - expect([...A].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.as_generator()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect([...A].map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); + expect([...A.all().js]).toEqual(['A', 'B', 'C']); + expect([...A.as_generator()].map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); expect(A.as_string()).toBe('A,B,C'); { @@ -1243,7 +1272,7 @@ describe("Ray", () => { array.push(current.value); } - expect(array.map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); + expect(array.map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); } @@ -1258,15 +1287,15 @@ describe("Ray", () => { B = A.next(); expect(B.type).toBe(RayType.VERTEX); - expect(B.self.any.js).toBe('B'); + expect(B.any.js).toBe('B'); expect(B.self .initial.self.initial - .any.js + .as_reference().any.js ).toBe('A'); expect(B.self .initial.self.initial .terminal.self.terminal - .any.js + .as_reference().any.js ).toBe('B'); }); test(".vertex.#.compose(.vertex.#)", () => { @@ -1276,15 +1305,15 @@ describe("Ray", () => { B = A.compose(B); expect(B.type).toBe(RayType.VERTEX); - expect(B.self.any.js).toBe('B'); + expect(B.any.js).toBe('B'); expect(B.self .initial.self.initial - .any.js + .as_reference().any.js ).toBe('A'); expect(B.self .initial.self.initial .terminal.self.terminal - .any.js + .as_reference().any.js ).toBe('B'); }); test("[.vertex.#, .vertex.#].#.compose", () => { @@ -1297,15 +1326,15 @@ describe("Ray", () => { }).as_reference().compose(); expect(B.type).toBe(RayType.VERTEX); - expect(B.self.any.js).toBe('B'); + expect(B.any.js).toBe('B'); expect(B.self .initial.self.initial - .any.js + .as_reference().any.js ).toBe('A'); expect(B.self .initial.self.initial .terminal.self.terminal - .any.js + .as_reference().any.js ).toBe('B'); }); // test(".vertex.#.debug", () => { TODO @@ -1319,25 +1348,25 @@ describe("Ray", () => { // expect(debug).toEqual('') // }) test(".as_arbitrary", () => { - expect(Ray.vertex().o({ js: 'A' }).as_arbitrary()().any.js).toBe('A'); + expect(Ray.vertex().o({ js: 'A' }).as_arbitrary()().as_reference().any.js).toBe('A'); }); test(".dereference", () => { const A = Ray.vertex( Ray.vertex().o({ js: "A.vertex" }).as_arbitrary() ).o({ js: 'A' }).as_reference(); - expect(A.dereference.self.any.js).toBe('A.vertex'); - expect(A.as_reference().dereference.self.any.js).toBe('A'); - expect(A.as_reference().as_reference().dereference.dereference.self.any.js).toBe('A'); - expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.self.any.js).toBe('A'); - expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.dereference.self.any.js).toBe('A.vertex'); + expect(A.dereference.any.js).toBe('A.vertex'); + expect(A.as_reference().dereference.any.js).toBe('A'); + expect(A.as_reference().as_reference().dereference.dereference.any.js).toBe('A'); + expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.any.js).toBe('A'); + expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.dereference.any.js).toBe('A.vertex'); }); test(".o", () => { const ray = Ray.vertex().o({ a: 'b', position: [0, 1, 2], func: () => 'c' - }); + }).as_reference(); expect(ray.any.a).toBe('b'); expect(ray.any.test).toBe(undefined); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 840cba3..798fe0d 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -313,7 +313,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) throw new PreventsImplementationBug(); - // ${[...initial.self.initial.as_reference().traverse()].map(ref => ref.self.any.js)} + // ${[...initial.self.initial.as_reference().all().js]} if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) { throw new PreventsImplementationBug(`[${initial.type}] - [${terminal.type}] - only composing vertices for now (${initial.self.initial.any.js} -> ${terminal.self.terminal.any.js})`); } @@ -392,7 +392,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? throw new PreventsImplementationBug('wut2') } - // if (terminal.self.self.any.js === 'D') + // if (terminal.self.any.js === 'D') // throw new PreventsImplementationBug(); initial.dereference.compose(terminal.dereference); @@ -452,9 +452,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // throw new PreventsImplementationBug(); // // if (!a.self.self.is_none()) - // throw new PreventsImplementationBug(`${b.self.self.self.any.js}`); + // throw new PreventsImplementationBug(`${b.self.self.any.js}`); // if (!b.self.self.is_none()) - // throw new PreventsImplementationBug(`${b.self.self.self.any.js}`); + // throw new PreventsImplementationBug(`${b.self.self.any.js}`); // // a.equivalent(b); // @@ -617,7 +617,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? pointer = pointer.step().step(); if (pointer.terminal.type !== RayType.VERTEX) - throw new NotImplementedError(`${pointer.terminal.type} / ${pointer.terminal.self.self.any.js}`); + throw new NotImplementedError(`${pointer.terminal.type} / ${pointer.terminal.self.any.js}`); return pointer.terminal; @@ -849,6 +849,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? for (let pointer of this.___traverse({step})) { // TODO: You can do this non-locally with a pass over the history. This way it's local, but we''ll have to find a good example of why this might not go that well. (As this would match to any empty vertices, and maybe more) + + // TODO: Could also check for none.. const { initial: previous, terminal: current } = pointer; if (previous.is_vertex() && !Ray.is_orbit(previous.self, current)) { @@ -856,6 +858,13 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } } } + *___map(map: (vertex: Ray) => T, { + step = Ray.directions.next, + } = {}): Generator { + for (let vertex of this.___next({step})) { + yield map(vertex); + } + } /** * TODO: Not happy with this... @@ -1044,25 +1053,59 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? as_array = (): Ray[] => [...this]; // JS.String toString = (): string => this.as_string(); - as_string = (): string => this.as_array().map(ref => ref.self.any.js).join(','); // TODO: PROPER + as_string = (): string => this.as_array().map(ref => ref.any.js).join(','); // TODO: PROPER as_int = (): number => { throw new NotImplementedError(); } as_number = this.as_int; - // all = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } - // get all(): { [key: string | symbol]: Ray } & any { return this.proxy(); } + /** + * + * TODO: + * - This needs something much smarter at some point... + */ + all = (step: Implementation = Ray.directions.next): { [key: string | symbol]: Ray } & any => { + return new Proxy(this, { + + get(self: Ray, p: string | symbol, receiver: any): any { + + return self.___map(ref => ref.any[p], {step}); + }, + + /** + * Can't overload things like '-=' for anything but things that return numbers... ; So just apply a general function instead. + */ + set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { + for (let ref of self.___next({step})) { // TODO; This needs to either be dynamically, or just a simple shut-off for circular ones. + ref.any[p] = JS.is_function(newValue) ? newValue(ref.any[p]) : newValue; + } + + return true; + }, + + + deleteProperty(self: Ray, p: string | symbol): boolean { + throw new NotImplementedError(); + + return true; + } + // TODO: What do these other methods on Proxy do??? + }); + + } /** * Move to a JavaScript object, which will handle any complexity of existing JavaScript objects, and allows one to abstract any values contained in the {vertex} to the usual JavaScript interface. - More usual to how one thinks about functions, ..., properties. */ - get any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } + get any(): { [key: string | symbol]: Ray } & any { return this.self.proxy(); } cast = (): T => { throw new NotImplementedError(); } // TODO this.proxy(); /** * Used for chaining JavaScript-provided properties + * + * TODO: DOESNT FOLLOW .ANY PATTERN? */ o = (object: { [key: string | symbol]: any }): Ray => { - _.keys(object).forEach(key => this.any[key] = object[key]); // TODO: Can be prettier, TODO: map to Ray equivalents and add to vertices.. + _.keys(object).forEach(key => this.proxy()[key] = object[key]); // TODO: Can be prettier, TODO: map to Ray equivalents and add to vertices.. return this; } @@ -1138,7 +1181,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? ...this._dirty_store, position: target_ray.any.position - ?? this.self.any.position + ?? this.any.position ?? Ray.POSITION_OF_DOOM }); console.log('move', `${this.self.label.split(' ')[0]} -> ${target.self.label.split(' ')[0]}`); @@ -1161,18 +1204,18 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? render_options = (Interface: Ray): Required => { return ({ position: - this.self.any.position + this.any.position ?? (this.is_none() ? Ray.POSITION_OF_DOOM : Ray.POSITION_OF_DOOM), rotation: - this.self.any.rotation + this.any.rotation ?? [0, 0, 0], scale: - this.self.any.scale + this.any.scale ?? (this.is_none() ? 1.5 : 1.5), color: (Ray.is_orbit(Interface.any.selection.self, this.self) && Interface.any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) : ( - this.self.any.color + this.any.color ?? (this.is_none() ? 'red' : { [RayType.VERTEX]: 'orange', [RayType.TERMINAL]: '#FF5555', diff --git a/src/@orbitmines/external/chyp/Chyp.spec.ts b/src/@orbitmines/external/chyp/Chyp.spec.ts index 35e283f..4902ac4 100644 --- a/src/@orbitmines/external/chyp/Chyp.spec.ts +++ b/src/@orbitmines/external/chyp/Chyp.spec.ts @@ -8,9 +8,9 @@ describe("Chyp", () => { .set_inputs(Ray.vertex().o({ js: 'B' }).as_arbitrary()) .set_inputs(Ray.vertex().o({ js: 'A' }).as_arbitrary()); - expect(graph.inputs.any.js).toBe('A'); - expect(graph.initial.any.js).toBe('A'); - expect(graph.inputs.any.js).toBe(graph.initial.any.js); + expect(graph.inputs.as_reference().any.js).toBe('A'); + expect(graph.initial.as_reference().any.js).toBe('A'); + expect(graph.inputs.as_reference().any.js).toBe(graph.initial.as_reference().any.js); expect(graph.inputs).toBe(graph.initial); }); diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index fa9b29f..739f012 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -134,13 +134,13 @@ import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; const ___index = (ray: Ray): number => { switch (ray.type) { case RayType.REFERENCE: - return ray.self.any.index ?? 0; + return ray.any.index ?? 0; case RayType.INITIAL: return ray.self.terminal.any.index ?? 0; case RayType.TERMINAL: return ray.self.initial.any.index ?? 0; case RayType.VERTEX: - return ray.self.any.index ?? 0; + return ray.any.index ?? 0; } } @@ -272,7 +272,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { const next = Ray.vertex().o2({ initial: { position: add_(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, - vertex: { index: Interface.any.selection.self.any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, + vertex: { index: Interface.any.selection.any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, terminal: { position: add_(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } }).as_reference().o({ ...selection.as_reference().render_options(Interface), @@ -483,7 +483,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { const next = Ray.vertex().o2({ initial: { position: add_(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, - vertex: { index: Interface.any.selection.self.any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, + vertex: { index: Interface.any.selection.any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, terminal: { position: add_(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } }).as_reference().o({ ...selection.as_reference().render_options(Interface), From f4d95343ff0d66e3ee64216170342dcf0120faa7 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Fri, 19 Jan 2024 00:01:36 +0100 Subject: [PATCH 104/138] 2024/01/18 - More .any to a reference '.any.[]' pattern, introduce .all for applying functions based on arbitrary continuations --- src/@orbitmines/explorer/Ray.ts | 7 +- .../explorer/debug/DebugCanvas.tsx | 55 ++--- src/@orbitmines/external/chyp/ChypCanvas.tsx | 190 +++++++++--------- 3 files changed, 127 insertions(+), 125 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 798fe0d..ea1971f 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1097,6 +1097,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * Move to a JavaScript object, which will handle any complexity of existing JavaScript objects, and allows one to abstract any values contained in the {vertex} to the usual JavaScript interface. - More usual to how one thinks about functions, ..., properties. */ get any(): { [key: string | symbol]: Ray } & any { return this.self.proxy(); } + get ___any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } cast = (): T => { throw new NotImplementedError(); } // TODO this.proxy(); /** @@ -1188,11 +1189,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (memory) { if (!target_ray.any.traversed) { - Interface.any.rays.push(target); + Interface.___any.rays.push(target); target_ray.any.traversed = true; } } else { - Interface.any.rays = [target]; + Interface.___any.rays = [target]; } return target; @@ -1213,7 +1214,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? this.any.scale ?? (this.is_none() ? 1.5 : 1.5), color: - (Ray.is_orbit(Interface.any.selection.self, this.self) && Interface.any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) + (Ray.is_orbit(Interface.___any.selection.self, this.self) && Interface.___any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) : ( this.any.color ?? (this.is_none() ? 'red' : { diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index bb3578f..f1497fa 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -75,72 +75,73 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { }), rays: [] as Ray[], stats: false, + cursor: { tick: false }, controls: Ray.vertex().o({ hotkeys: [ { combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { - Interface.any.selection = Interface.any.selection.move((self: Ray) => self.initial, memory, Interface); + Interface.___any.selection = Interface.___any.selection.move((self: Ray) => self.initial, memory, Interface); } }, { combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { - Interface.any.selection = Interface.any.selection.move((self: Ray) => self.terminal, memory, Interface); + Interface.___any.selection = Interface.___any.selection.move((self: Ray) => self.terminal, memory, Interface); } }, { combo: ["delete"], global: true, label: "", onKeyDown: () => { - Interface.any.rays = Interface.any.rays.filter((ray: Ray) => ray.self.label !== Interface.any.selection.self.label); // Should be automatic, this sort of thing - Interface.any.selection = Interface.any.selection.delete; + Interface.___any.rays = Interface.___any.rays.filter((ray: Ray) => ray.self.label !== Interface.___any.selection.self.label); // Should be automatic, this sort of thing + Interface.___any.selection = Interface.___any.selection.delete; } }, { combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { // TODO SHOULD BE ANOTHER DIRECTION AT THE FRAME? - Interface.any.selection = Interface.any.selection.move((self: Ray) => self.self, memory, Interface); + Interface.___any.selection = Interface.___any.selection.move((self: Ray) => self.self, memory, Interface); } }, { combo: ["e"], global: true, label: "", onKeyDown: () => { const change = [0, 0, Math.PI / 10]; - console.log(Interface.any.selection.self.initial.label) + console.log(Interface.___any.selection.self.initial.label) - Interface.any.selection = Interface.any.selection.self.o2({ - initial: { rotation: add(Interface.any.selection.self.initial.any.rotation ?? [0, 0, 0], change) }, - terminal: { rotation: add(Interface.any.selection.self.terminal.any.rotation ?? [0, 0, 0], change) }, + Interface.___any.selection = Interface.___any.selection.self.o2({ + initial: { rotation: add(Interface.___any.selection.self.initial.___any.rotation ?? [0, 0, 0], change) }, + terminal: { rotation: add(Interface.___any.selection.self.terminal.___any.rotation ?? [0, 0, 0], change) }, }) } }, { combo: ["space"], global: true, label: "", onKeyDown: (e) => { e.preventDefault(); - Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { - ray.any.traversed = true; + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.___any.traversed = true; return ray.as_reference(); }); } }, // { // combo: ["s", "arrowdown"], global: true, label: "", onKeyDown: () => { - // Interface.any.selection = Interface.any.selection.move((self: Ray) => self.as_reference().as_reference(), memory, Interface); + // Interface.___any.selection = Interface.___any.selection.move((self: Ray) => self.as_reference().as_reference(), memory, Interface); // } // }, { combo: "/", global: true, label: "", onKeyDown: () => { console.log('---------') - console.log(`Debugging: ${Interface.any.selection.self.label} (type=${Interface.any.selection.type})`) - console.log(`rays.length at pos=[${Interface.any.selection.render_options.position}]: ${Interface.any.rays.filter((ray: Ray) => + console.log(`Debugging: ${Interface.___any.selection.self.label} (type=${Interface.___any.selection.type})`) + console.log(`rays.length at pos=[${Interface.___any.selection.render_options.position}]: ${Interface.___any.rays.filter((ray: Ray) => _.isEqual( - Interface.any.selection.render_options.position, + Interface.___any.selection.render_options.position, ray.render_options(Interface).position ) - ).length} / ${Interface.any.rays.length}`) - console.log('ref', Interface.any.selection) - console.log('ref.self', Interface.any.selection.self) + ).length} / ${Interface.___any.rays.length}`) + console.log('ref', Interface.___any.selection) + console.log('ref.self', Interface.___any.selection.self) const debug: DebugResult = {}; - Interface.any.selection.self.debug(debug); + Interface.___any.selection.self.debug(debug); console.log('ref.debug', debug); - Interface.any.rays.forEach((ray: Ray) => ray.debug(debug)); + Interface.___any.rays.forEach((ray: Ray) => ray.debug(debug)); console.log('rays.debug', debug); } @@ -148,7 +149,7 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { { combo: "f3", global: true, label: "Show stats Panel", onKeyDown: (e) => { e.preventDefault(); - Interface.any.stats = !Interface.any.stats; + Interface.___any.stats = !Interface.___any.stats; } }, ] as HotkeyConfig[] @@ -157,16 +158,16 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { // useEffect(() => { // TODO: Eventually goes over maximum size of react-debug callstack when updates each frame like this. - hotkeyConfig.set(...Interface.any.controls.any.hotkeys); - // }, [Interface.any.controls.any.hotkeys]); + hotkeyConfig.set(...Interface.___any.controls.___any.hotkeys); + // }, [Interface.___any.controls.___any.hotkeys]); return <> - {Interface.any.stats ? : <>} + {Interface.___any.stats ? : <>} - + - {/*{Interface.any.rays.map((ray: Ray) => )}*/} - {Interface.any.rays.map((ray: Ray) => )} + {/*{Interface.___any.rays.map((ray: Ray) => )}*/} + {Interface.___any.rays.map((ray: Ray) => )} } diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index 739f012..aa11824 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -134,13 +134,13 @@ import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; const ___index = (ray: Ray): number => { switch (ray.type) { case RayType.REFERENCE: - return ray.any.index ?? 0; + return ray.___any.index ?? 0; case RayType.INITIAL: - return ray.self.terminal.any.index ?? 0; + return ray.follow().___any.index ?? 0; case RayType.TERMINAL: - return ray.self.initial.any.index ?? 0; + return ray.follow(Ray.directions.previous).___any.index ?? 0; case RayType.VERTEX: - return ray.any.index ?? 0; + return ray.___any.index ?? 0; } } @@ -262,26 +262,26 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { }), rays: [] as Ray[], stats: false, - controls: Ray.vertex().o({ + controls: { hotkeys: [ { combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { - const { selection, rays } = Interface.any; + const { selection, rays } = Interface.___any; - const current = Interface.any.selection.render_options(Interface); + const current = Interface.___any.selection.render_options(Interface); const next = Ray.vertex().o2({ initial: { position: add_(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, - vertex: { index: Interface.any.selection.any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, + vertex: { index: Interface.___any.selection.___any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, terminal: { position: add_(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } }).as_reference().o({ ...selection.as_reference().render_options(Interface), - position: add(selection.any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) + position: add(selection.___any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) }); - Interface.any.selection = selection.compose(next); - Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { - ray.any.traversed = true; + Interface.___any.selection = selection.compose(next); + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.___any.traversed = true; return ray.as_reference(); }); @@ -289,53 +289,53 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { }, { combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { - if (Interface.any.rays.length === 0) + if (Interface.___any.rays.length === 0) return; - Interface.any.selection = Interface.any.selection.pop(); - Interface.any.selection.o({ - position: Interface.any.selection.render_options(Interface).position + Interface.___any.selection = Interface.___any.selection.pop(); + Interface.___any.selection.o({ + position: Interface.___any.selection.render_options(Interface).position }); // TODO, Same with this. - Interface.any.selection.self.terminal.o({ - position: add(Interface.any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' + Interface.___any.selection.self.terminal.o({ + position: add(Interface.___any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. - Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { - ray.any.traversed = true; + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.___any.traversed = true; return ray.as_reference(); }); - if (Interface.any.length === 0) { - Interface.any.selection.any.position = [0, 0, 0] + if (Interface.___any.length === 0) { + Interface.___any.selection.___any.position = [0, 0, 0] return; } } }, { combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { - const { selection, rays } = Interface.any; + const { selection, rays } = Interface.___any; - Interface.any.rays = rays.flatMap((ray: Ray) => [ + Interface.___any.rays = rays.flatMap((ray: Ray) => [ ray, // Ray.js("A").as_reference().o({ // // ...ray.o, - // position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]) + // position: add(ray.___any.position ?? [0, 0, 0], [0, i * 2, 0]) // }), // Ray.js("A").as_reference().o({ // // ...ray.o, - // position: ray.any.position, + // position: ray.___any.position, // rotation: [0, 0, Math.PI / 2] // }), // Ray.js("A").as_reference().o({ // // ...ray.o, - // position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]), + // position: add(ray.___any.position ?? [0, 0, 0], [0, i * 2, 0]), // rotation: [0, 0, Math.PI / 2] // }) ]); - // Chyp_naieve_pass.any.selection = Chyp_naieve_pass; + // Chyp_naieve_pass.___any.selection = Chyp_naieve_pass; - // selection.o({...selection.o, position: add(selection.any.position ?? [0, 0, 0], [0, i * 2, 0])}) + // selection.o({...selection.o, position: add(selection.___any.position ?? [0, 0, 0], [0, i * 2, 0])}) // selection.compose( @@ -345,20 +345,20 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { { combo: "/", global: true, label: "", onKeyDown: () => { console.log('---------') - console.log(`Debugging: ${Interface.any.selection.self.label} (type=${Interface.any.selection.type})`) - console.log(`rays.length at pos=[${Interface.any.selection.render_options(Interface).position}]: ${Interface.any.rays.filter((ray: Ray) => + console.log(`Debugging: ${Interface.___any.selection.self.label} (type=${Interface.___any.selection.type})`) + console.log(`rays.length at pos=[${Interface.___any.selection.render_options(Interface).position}]: ${Interface.___any.rays.filter((ray: Ray) => _.isEqual( - Interface.any.selection.render_options.position, + Interface.___any.selection.render_options.position, ray.render_options(Interface).position ) - ).length} / ${Interface.any.rays.length}`) - console.log('ref', Interface.any.selection) - console.log('ref.self', Interface.any.selection.self) + ).length} / ${Interface.___any.rays.length}`) + console.log('ref', Interface.___any.selection) + console.log('ref.self', Interface.___any.selection.self) const debug: DebugResult = {}; - Interface.any.selection.self.debug(debug); + Interface.___any.selection.self.debug(debug); console.log('ref.debug', debug); - Interface.any.rays.forEach((ray: Ray) => ray.debug(debug)); + Interface.___any.rays.forEach((ray: Ray) => ray.debug(debug)); console.log('rays.debug', debug); } @@ -366,44 +366,44 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { { combo: "f3", global: true, label: "Show stats Panel", onKeyDown: (e) => { e.preventDefault(); - Interface.any.stats = !Interface.any.stats; + Interface.___any.stats = !Interface.___any.stats; } }, ] as HotkeyConfig[] - }) + } })); // useEffect(() => { // TODO: Eventually goes over maximum size of react-debug callstack when updates each frame like this. - hotkeyConfig.set(...Interface.any.controls.any.hotkeys); - // }, [Interface.any.controls.any.hotkeys]); + hotkeyConfig.set(...Interface.___any.controls.hotkeys); + // }, [Interface.___any.controls.___any.hotkeys]); - const index = ___index(Interface.any.selection); + const index = ___index(Interface.___any.selection); const added = [15 * index, 60 * (index + 1), 0]; return <> - {Interface.any.stats ? : <>} + {Interface.___any.stats ? : <>} - - {/*{Interface.any.rays.map((ray: Ray) => )}*/} + {/*{Interface.___any.rays.map((ray: Ray) => )}*/} - {Interface.any.rays.map((ray: Ray) => )} + {Interface.___any.rays.map((ray: Ray) => )} - - {Interface.any.rays.map((ray: Ray, index: number) => )} + {Interface.___any.rays.map((ray: Ray, index: number) => )} - - {Interface.any.rays.map((ray: Ray, index: number) => )} + {Interface.___any.rays.map((ray: Ray, index: number) => )} @@ -473,26 +473,26 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { cursor: { tick: false }, - controls: Ray.vertex().o({ + controls: { hotkeys: [ { combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { - const { selection, rays } = Interface.any; + const { selection, rays } = Interface.___any; - const current = Interface.any.selection.render_options(Interface); + const current = Interface.___any.selection.render_options(Interface); const next = Ray.vertex().o2({ initial: { position: add_(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, - vertex: { index: Interface.any.selection.any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, + vertex: { index: Interface.___any.selection.___any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, terminal: { position: add_(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } }).as_reference().o({ ...selection.as_reference().render_options(Interface), - position: add(selection.any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) + position: add(selection.___any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) }); - Interface.any.selection = selection.compose(next); - Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { - ray.any.traversed = true; + Interface.___any.selection = selection.compose(next); + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.___any.traversed = true; return ray.as_reference(); }); @@ -500,53 +500,53 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { }, { combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { - if (Interface.any.rays.length === 0) + if (Interface.___any.rays.length === 0) return; - Interface.any.selection = Interface.any.selection.pop(); - Interface.any.selection.o({ - position: Interface.any.selection.render_options(Interface).position + Interface.___any.selection = Interface.___any.selection.pop(); + Interface.___any.selection.o({ + position: Interface.___any.selection.render_options(Interface).position }); // TODO, Same with this. - Interface.any.selection.self.terminal.o({ - position: add(Interface.any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' + Interface.___any.selection.self.terminal.o({ + position: add(Interface.___any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. - Interface.any.rays = Interface.any.selection.self.___dirty_all([]).map((ray: Ray) => { - ray.any.traversed = true; + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + ray.___any.traversed = true; return ray.as_reference(); }); - if (Interface.any.length === 0) { - Interface.any.selection.any.position = [0, 0, 0] + if (Interface.___any.length === 0) { + Interface.___any.selection.___any.position = [0, 0, 0] return; } } }, { combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { - const { selection, rays } = Interface.any; + const { selection, rays } = Interface.___any; - Interface.any.rays = rays.flatMap((ray: Ray) => [ + Interface.___any.rays = rays.flatMap((ray: Ray) => [ ray, // Ray.js("A").as_reference().o({ // // ...ray.o, - // position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]) + // position: add(ray.___any.position ?? [0, 0, 0], [0, i * 2, 0]) // }), // Ray.js("A").as_reference().o({ // // ...ray.o, - // position: ray.any.position, + // position: ray.___any.position, // rotation: [0, 0, Math.PI / 2] // }), // Ray.js("A").as_reference().o({ // // ...ray.o, - // position: add(ray.any.position ?? [0, 0, 0], [0, i * 2, 0]), + // position: add(ray.___any.position ?? [0, 0, 0], [0, i * 2, 0]), // rotation: [0, 0, Math.PI / 2] // }) ]); - // Chyp_naieve_pass.any.selection = Chyp_naieve_pass; + // Chyp_naieve_pass.___any.selection = Chyp_naieve_pass; - // selection.o({...selection.o, position: add(selection.any.position ?? [0, 0, 0], [0, i * 2, 0])}) + // selection.o({...selection.o, position: add(selection.___any.position ?? [0, 0, 0], [0, i * 2, 0])}) // selection.compose( @@ -556,53 +556,53 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { { combo: "/", global: true, label: "", onKeyDown: () => { console.log('---------') - console.log(`Debugging: ${Interface.any.selection.self.label} (type=${Interface.any.selection.type})`) - console.log(`rays.length at pos=[${Interface.any.selection.render_options(Interface).position}]: ${Interface.any.rays.filter((ray: Ray) => + console.log(`Debugging: ${Interface.___any.selection.self.label} (type=${Interface.___any.selection.type})`) + console.log(`rays.length at pos=[${Interface.___any.selection.render_options(Interface).position}]: ${Interface.___any.rays.filter((ray: Ray) => _.isEqual( - Interface.any.selection.render_options(Interface).position, + Interface.___any.selection.render_options(Interface).position, ray.render_options(Interface).position ) - ).length} / ${Interface.any.rays.length}`) - console.log('ref', Interface.any.selection) - console.log('ref.self', Interface.any.selection.self) + ).length} / ${Interface.___any.rays.length}`) + console.log('ref', Interface.___any.selection) + console.log('ref.self', Interface.___any.selection.self) const debug: DebugResult = {}; - Interface.any.selection.self.debug(debug); + Interface.___any.selection.self.debug(debug); console.log('ref.debug', debug); - Interface.any.rays.forEach((ray: Ray) => ray.debug(debug)); + Interface.___any.rays.forEach((ray: Ray) => ray.debug(debug)); console.log('rays.debug', debug); } }, { combo: "f3", global: true, label: "Show stats Panel", onKeyDown: (e) => { e.preventDefault(); - Interface.any.stats = !Interface.any.stats; + Interface.___any.stats = !Interface.___any.stats; } }, ] as HotkeyConfig[] - }) + } })); // useEffect(() => { // TODO: Eventually goes over maximum size of react-debug callstack when updates each frame like this. - hotkeyConfig.set(...Interface.any.controls.any.hotkeys); - // }, [Interface.any.controls.any.hotkeys]); + hotkeyConfig.set(...Interface.___any.controls.hotkeys); + // }, [Interface.___any.controls.___any.hotkeys]); useEffect(() => { setInterval(() => { - Interface.any.cursor.tick = !Interface.any.cursor.tick; + Interface.___any.cursor.tick = !Interface.___any.cursor.tick; // TODO THIS NEEDS TO BE EASIER }, 500); // TODO; On react reload interval is not destroyed }, []); return <> - {Interface.any.stats ? : <>} + {Interface.___any.stats ? : <>} - + - {Interface.any.rays.map((ray: Ray) => )} + {Interface.___any.rays.map((ray: Ray) => )} } @@ -610,7 +610,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { // // TODO: Direct call to rerender on change, now there's lag // // const Rendered = ({ ray, ...options }: { ray: Ray } & InterfaceOptions) => { -// const { position = options.position, rotation = options.rotation, scale = options.scale, color = options.color } = ray.any; +// const { position = options.position, rotation = options.rotation, scale = options.scale, color = options.color } = ray.___any; // return ; // } // @@ -621,9 +621,9 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { // // return <> //
-// {/**/} -// {/**/} -// {/**/} +// {/**/} +// {/**/} +// {/**/} // // {/**/} // From 229fd109f59b72288cddab597c31c35e5a34b2d6 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Fri, 19 Jan 2024 16:04:18 +0100 Subject: [PATCH 105/138] 2024/01/19 - Going to do a large refactor - some of these aren't great to work with. TODO: Only local changes by default. no push_back, Only influence surrounding 3 rays. --- src/@orbitmines/explorer/Ray.spec.ts | 182 ++++++++++++---- src/@orbitmines/explorer/Ray.ts | 296 +++++++++++++++++---------- 2 files changed, 329 insertions(+), 149 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 56026dd..6435e6a 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -30,7 +30,35 @@ describe("Ray", () => { expect(() => A.copy()).toThrow(); //TODO // const copy = A.copy(); // expect(A.has_previous()).toBe(false); + // expect(copy.has_previous()).toBe(false); + }); + test("[A, [B, C]]", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + + /** + * [--A--] [--| ] + * [ |--] [--B--] + */ + A.compose(B); + + /** + * [--A--] [--| ] + * [ |--] [--B--] + * | + * [ |--] [--C--] + */ + A.compose(C); + + expect(A.follow().type).toEqual(RayType.TERMINAL); + expect(A.follow().dereference.type).toEqual(RayType.VERTEX); + expect([...A.follow().dereference].map(ref => ref.self.follow_direction().any.js)).toEqual(['A', 'B', 'C']); + expect([...A.all().js]).toEqual(['A', 'B', 'C']); + // expect([...A].map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); + + }); test(".vertex.#.delete", () => { const A_vertex = Ray.vertex().o({ js: 'A' }); @@ -89,8 +117,10 @@ describe("Ray", () => { A.compose(B).compose(C).compose(D).compose(E); expect([...A.___next()].map(ref => ref.any.js)).toEqual(['A', 'B', 'C', 'D', 'E']); + expect(A.last().any.js).toEqual('E'); + expect(D.first().any.js).toEqual('A'); }); - test("[A, B, C].___traverse()", () => { + test("[A, B, C, D, E].___traverse()", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); @@ -100,21 +130,48 @@ describe("Ray", () => { A.compose(B).compose(C).compose(D).compose(E); expect([...A.___traverse()].map(pointer => - [pointer.initial.type, pointer.terminal.type, pointer.initial.any.js] + [pointer.terminal.is_none(), pointer.initial.type, pointer.terminal.type, pointer.initial.any.js] + )).toEqual([ + [false, RayType.VERTEX, RayType.TERMINAL, 'A'], + [false, RayType.TERMINAL, RayType.INITIAL, undefined], + [false, RayType.INITIAL, RayType.VERTEX, undefined], + [false, RayType.VERTEX, RayType.TERMINAL, 'B'], + [false, RayType.TERMINAL, RayType.INITIAL, undefined], + [false, RayType.INITIAL, RayType.VERTEX, undefined], + [false, RayType.VERTEX, RayType.TERMINAL, 'C'], + [false, RayType.TERMINAL, RayType.INITIAL, undefined], + [false, RayType.INITIAL, RayType.VERTEX, undefined], + [false, RayType.VERTEX, RayType.TERMINAL, 'D'], + [false, RayType.TERMINAL, RayType.INITIAL, undefined], + [false, RayType.INITIAL, RayType.VERTEX, undefined], + [false, RayType.VERTEX, RayType.TERMINAL, 'E'], + [true, RayType.TERMINAL, RayType.VERTEX, undefined], // vertex is Ray.None + ]); + }); + test("[A, [B, C, D]].___traverse()", () => { + // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); + // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + // + // A.compose(B); + // A.compose(C); + + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const A_terminal = A.follow(); + const B_initial = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }).follow(Ray.directions.previous); + const C_initial = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }).follow(Ray.directions.previous); + const D_initial = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }).follow(Ray.directions.previous); + + A_terminal.equivalent(B_initial); + A_terminal.equivalent(C_initial); + A_terminal.equivalent(D_initial); + + expect([...A.___traverse()].map(pointer => + [pointer.terminal.is_none(), pointer.initial.type, pointer.terminal.type, pointer.terminal.is_boundary() ? pointer.terminal.follow_direction().any.js : undefined] )).toEqual([ - [RayType.VERTEX, RayType.TERMINAL, 'A'], - [RayType.TERMINAL, RayType.INITIAL, undefined], - [RayType.INITIAL, RayType.VERTEX, undefined], - [RayType.VERTEX, RayType.TERMINAL, 'B'], - [RayType.TERMINAL, RayType.INITIAL, undefined], - [RayType.INITIAL, RayType.VERTEX, undefined], - [RayType.VERTEX, RayType.TERMINAL, 'C'], - [RayType.TERMINAL, RayType.INITIAL, undefined], - [RayType.INITIAL, RayType.VERTEX, undefined], - [RayType.VERTEX, RayType.TERMINAL, 'D'], - [RayType.TERMINAL, RayType.INITIAL, undefined], - [RayType.INITIAL, RayType.VERTEX, undefined], - [RayType.VERTEX, RayType.TERMINAL, 'E'], + [false, RayType.VERTEX, RayType.TERMINAL, 'A'], + [false, RayType.TERMINAL, RayType.VERTEX, undefined], + // [true, RayType.VERTEX, RayType.VERTEX, undefined], ]); }); test("[A, B, C].next()", () => { @@ -965,28 +1022,79 @@ describe("Ray", () => { expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); expect([...R.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['R']); }); - // test("(A:vertex.# = B:vertex.#) ; A.as_terminal", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // - // A.equivalent(B); - // - // const terminal = A.as_terminal(); - // - // expect(terminal.type).toBe(RayType.TERMINAL); - // - // expect([...terminal.follow(Ray.directions.previous).all(Ray.directions.previous).js]).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); - // - // /** - // * These should keep looping... - // * TODO: Better test helper for this - // */ - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); - // }); + test("(A:terminal.# = B:initial.#) ; A.as_terminal", () => { + const A_terminal = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }).follow(); + const B_initial = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }).follow(Ray.directions.previous); + + /** + * A ____________ B + * [--|--][--| ][ |--][--|--] + */ + A_terminal.equivalent(B_initial); + + /** + * | + * [ |--][--B--] + * | + * [--A--][--| ] <--- ret + * | + */ + const ret = A_terminal.as_terminal(); + expect(ret.type).toBe(RayType.TERMINAL); + + expect([...A_terminal.dereference.all().js]).toEqual(['___as_vertex', '___as_vertex']); + expect([...A_terminal.dereference.___map(ref => ref.self.follow_direction().any.js)]).toEqual(['A', 'B']); + }); + test("(A:terminal.# = B:initial.# = C:initial.#) ; A.as_terminal", () => { + const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); + const A_terminal = A.follow(); + const B_initial = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }).follow(Ray.directions.previous); + const C_initial = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }).follow(Ray.directions.previous); + const D_initial = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }).follow(Ray.directions.previous); + + /** + * A ____________ B + * [--|--][--| ][ |--][--|--] + */ + A_terminal.equivalent(B_initial); + + expect([...A_terminal.dereference.all().js]).toEqual(['B']); + expect([...A_terminal.dereference.___map(ref => ref.any.js)]).toEqual(['B']); + + expect([...B_initial.dereference.all(Ray.directions.previous).js]).toEqual(['A']); + expect([...B_initial.dereference.___map(ref => ref.any.js, { step: Ray.directions.previous})]).toEqual(['A']); + + /** + * | + * [--A--][--| ] + * | + * [ |--][--B--] + * | + * [ |--][--C--] + * | + */ + A_terminal.equivalent(C_initial); + + expect([...A_terminal.dereference.all().js]).toEqual(['___as_vertex', '___as_vertex', '___as_vertex']); + expect([...A_terminal.dereference.___map(ref => ref.self.follow_direction().any.js)]).toEqual(['A', 'B', 'C']); + + /** + * | + * [--A--][--| ] + * | + * [ |--][--B--] + * | + * [ |--][--C--] + * | + * [ |--][--D--] + * | + */ + A_terminal.equivalent(D_initial); + + expect([...A_terminal.dereference.all().js]).toEqual(['___as_vertex', '___as_vertex', '___as_vertex', '___as_vertex']); + expect([...A_terminal.dereference.___map(ref => ref.self.follow_direction().any.js)]).toEqual(['A', 'B', 'C', 'D']); + expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D']); + }); // test("(A:vertex.# = B:vertex.#) ; B.as_terminal", () => { // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index ea1971f..99319fd 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -196,59 +196,48 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // // return initial_vertex.follow(Ray.directions.previous); // } - // /** - // * Moves `this.self` and `this.self.self` to a new line. - // * - // * [ |--] this.self.self ----- this.self [--|--] - // * _____ (<- terminal pointer) - // */ - // as_terminal = (): Ray => { - // if (this.is_none()) { - // throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); - // } - // if (this.dereference.is_none()) { - // // TODO: Need some intuition for this check - // const vertex = this.___as_vertex(); - // - // if (vertex.type !== RayType.VERTEX) - // throw new PreventsImplementationBug(); - // - // return vertex.follow(); - // } - // - // const [initial_vertex, terminal_vertex] = this.___as_vertices(); - // - // if (initial_vertex.type !== RayType.VERTEX) - // throw new PreventsImplementationBug(); - // if (terminal_vertex.type !== RayType.VERTEX) - // throw new PreventsImplementationBug(); - // - // initial_vertex.compose(terminal_vertex); - // - // // TODO BETTER DEBUG - // - // return terminal_vertex.follow(); - // } - // private ___as_vertices = (): [Ray, Ray] => { - // if (!Ray.is_orbit(this.self, this.self.self.self)) - // throw new PreventsImplementationBug('Is there a use-case for this? Probably not?'); //TODO - // - // // TODO NOTE: THE ORDER OF `this.self` first matters here. - // return [this.self.___as_vertex(), this.___as_vertex()]; - // } - // private ___as_vertex = (): Ray => { - // const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); - // - // // this.self.self = vertex.self.as_arbitrary(); - // // vertex.self.self = this.self.as_arbitrary(); - // - // // return this.___ignorantly_equivalent(Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' })); - // - // return this.___ignorantly_equivalent(vertex); - // } + /** + * Moves `this.self` and `this.self.self` to a new line. + * + * [ |--] this.self.self ----- this.self [--|--] + * _____ (<- terminal pointer) + */ + as_terminal = (): Ray => { + if (this.is_none()) { + throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); + } + if (this.dereference.is_none()) { + throw new PreventsImplementationBug(); + } + + const [terminal_vertex, initial_vertex] = this.___as_vertices(); + + if (initial_vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + if (terminal_vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + + initial_vertex.compose(terminal_vertex); + + // TODO BETTER DEBUG + + return terminal_vertex.follow(); + } + private ___as_vertices = (): [Ray, Ray] => { + if (!Ray.is_orbit(this.self, this.self.self.self)) + throw new PreventsImplementationBug('Is there a use-case for this? Probably not?'); //TODO + + // TODO NOTE: THE ORDER OF `this.self` first matters here. + return [this.self.___as_vertex(), this.___as_vertex()]; + } + private ___as_vertex = (): Ray => { + const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + + return this.___ignorantly_equivalent(vertex); + } private ___ignorantly_equivalent = (ref: Ray): Ray => { - this.self.self = ref.self.as_arbitrary(); ref.self.self = this.self.as_arbitrary(); + this.self.self = ref.self.as_arbitrary(); return ref; } @@ -379,17 +368,32 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // return terminal; } + if (initial.is_boundary() && initial.dereference.is_boundary()) { + initial.as_terminal(); + //.follow(Ray.directions.previous).compose(terminal.dereference); + // return terminal; + } + if ( initial.dereference.type !== RayType.VERTEX || terminal.dereference.type !== RayType.VERTEX || initial.dereference.self === initial.self || terminal.dereference.self === terminal.self ) { - throw new PreventsImplementationBug('wut') + throw new PreventsImplementationBug(` + [${initial.type}](${initial.follow_direction().any.js}) + / [${initial.dereference.type}](${initial.dereference.follow_direction().any.js}) + -> ${terminal.type}${terminal.follow_direction().any.js}`) } if (initial.follow().type !== RayType.TERMINAL || terminal.follow(Ray.directions.previous).type !== RayType.INITIAL) { - throw new PreventsImplementationBug('wut2') + initial.dereference.push_back(terminal.dereference); // TODO: NON-PUSH-BACK VARIANT? (Just local splits?) + return terminal; + // throw new PreventsImplementationBug(` + // [${initial.type}](${initial.follow_direction().any.js}) + // / [${initial.dereference.type}] {${[...initial.dereference.traverse()].map(ref => ref.self.follow_direction().any.js)}} + // -> ${terminal.type} (${terminal.follow_direction().any.js}) + // / [${terminal.dereference.type}]`) } // if (terminal.self.any.js === 'D') @@ -598,28 +602,39 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return step(this); } + follow_direction = (): Ray => this.___primitive_switch({ + [RayType.INITIAL]: Ray.directions.next, + [RayType.TERMINAL]: Ray.directions.previous, + }); /** * .next */ next = (step: Implementation = Ray.directions.next): Ray => { + return [...this.traverse(step)][1] ?? Ray.None(); // TODO BAD + // for (let next of this.traverse(step)) { + // + // return next; + // } + // + // return Ray.None(); // for (let next of this.___next({step})) { // // // return next; // } // // return Ray.None(); - let pointer = new Ray({ - initial: () => this, - terminal: () => step(this), - }); - - pointer = pointer.step().step(); - - if (pointer.terminal.type !== RayType.VERTEX) - throw new NotImplementedError(`${pointer.terminal.type} / ${pointer.terminal.self.any.js}`); - - return pointer.terminal; + // let pointer = new Ray({ + // initial: () => this, + // terminal: () => step(this), + // }); + // + // pointer = pointer.step().step(); + // + // if (pointer.terminal.type !== RayType.VERTEX) + // throw new NotImplementedError(`${pointer.terminal.type} / ${pointer.terminal.self.any.js}`); + // + // return pointer.terminal; // return Ray.___next(Ray.directions.next)(this); } @@ -809,7 +824,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? initial: () => initial, terminal: () => step(initial) }); - private next_pointer = (step: Implementation) => { const { self: history, terminal: current } = this; @@ -820,29 +834,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }); }; - /** - * VERTEX (current) - * | - * v - * - * ? <-- Pointer B - * [--| ] <-- INITIAL/TERMINAL (previous) - * ? <-- Pointer A - */ - private branch = (): [Ray, Ray] => { - const { initial: previous, terminal: current } = this; - - if (!previous.is_boundary()) - throw new PreventsImplementationBug('Only branching off INITIAL/TERMINAL -> VERTEX for now.'); - if (current.type !== RayType.VERTEX) - throw new PreventsImplementationBug('Only branching off INITIAL/TERMINAL -> VERTEX for now.'); - - return [ - this.next_pointer(Ray.directions.previous), - this.next_pointer(Ray.directions.next) - ]; - } - *___next({ step = Ray.directions.next, } = {}): Generator { @@ -871,51 +862,134 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ *___traverse({ step = Ray.directions.next, - should_branch = (pointer: Ray) => { - const { initial: previous, terminal: current } = pointer; - return previous.is_boundary() && current.is_vertex() && Ray.is_orbit(current.self, previous); - }, - branch = (pointer: Ray): [Ray, Ray] => pointer.branch(), filter = (pointer: Ray): boolean => true, - next = (pointers: Ray[]): Ray => pointers[0], - remove = (pointers: Ray[], pointer: Ray) => delete pointers[0], + next = (pointers: Ray[]): Ray => pointers[pointers.length - 1], + remove = (pointers: Ray[]) => pointers.pop(), } = {}): Generator { const pointers: Ray[] = [ Ray.vertex(Ray.pointer(this, step).as_arbitrary()) ]; // TODO COuld be a ray; + let first = true; + while (true) { const ref = next(pointers); if (ref === undefined) { + remove(pointers); // TODO: Could just keep trying... break; } let { self: pointer } = ref; if (!filter(pointer)) { - remove(pointers, pointer); + remove(pointers); ///, pointer + first = false; // TODO REMOVE continue; } + if (!first) { // TODO THIS NEEDS TO BE BETTER + pointer = pointer.step(); + } + yield pointer; - pointer = pointer.step(); + const { initial, terminal } = pointer; - if (pointer.terminal.is_none()) { - remove(pointers, pointer); - continue; - } + if (!first) { - if (should_branch(pointer)) { - const [a, b] = branch(pointer); + // TODO: Same pattern as .step - ref.self = a.as_arbitrary(); - pointers.push(Ray.vertex(b.as_arbitrary())); - } else { - ref.self = pointer.as_arbitrary(); + /** + * VERTEX (current) + * | + * v + * + * ? <-- Pointer B + * [--| ] <-- INITIAL/TERMINAL (previous) + * ? <-- Pointer A + */ + const default_pointer = (): Ray[] => { + return pointer.terminal.is_none() ? [] : [pointer]; + } + const boundary = (boundary: Boundary): Ray[] => { + return terminal.___primitive_switch({ + [boundary]: default_pointer, + [opposite(boundary)]: default_pointer, + [RayType.REFERENCE]: default_pointer, + + [RayType.VERTEX]: () => { + if (Ray.is_orbit(terminal.self.self, initial.self)) { + return [ + this.next_pointer(Ray.directions.previous), + this.next_pointer(Ray.directions.next) + ]; + } + + if (terminal.dereference.is_boundary() && Ray.is_orbit(terminal.self.self.self, terminal.self)) { + + return [ + ...default_pointer(), + new Ray({ + initial: terminal.as_arbitrary(), + vertex: pointer.as_arbitrary(), + terminal: () => terminal.dereference + }) + ] + } + + return default_pointer(); + + // if (terminal.self.is_boundary() && Ray.is_orbit(terminal.self.self.self, terminal.self)) { + // + // return [ + // this.next_pointer(Ray.directions.next), + // this.next(current => current.self.self) + // ] + // } + // + // if (!Ray.is_orbit(terminal.self.self, initial.self)) + // return default_pointer(); + // + // return [ + // this.next_pointer(Ray.directions.previous), + // this.next_pointer(Ray.directions.next) + // ]; + }, + }) + } + + const branches: Ray[] = initial.___primitive_switch({ + [RayType.VERTEX]: (initial) => terminal.___primitive_switch({ + [RayType.VERTEX]: default_pointer, + [RayType.REFERENCE]: default_pointer, + + [RayType.INITIAL]: default_pointer, + [RayType.TERMINAL]: default_pointer, + }), + + [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL), + [RayType.TERMINAL]: (initial) => boundary(RayType.TERMINAL), + + [RayType.REFERENCE]: default_pointer, + }); + + if (branches.length === 0) { + remove(pointers); // pointer, + } else { + ref.self = branches[0].as_arbitrary(); + + if (branches.length !== 1) { + pointers.push(...branches.slice(1).map(b => Ray.vertex(b.as_arbitrary()))); + } + } } + + first = false; // TODO REMOVE } + + if (pointers.length !== 0) + throw new PreventsImplementationBug(`${pointers.length} left`) } /** @@ -957,10 +1031,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * INITIAL/TERMINAL -> possible previous - TERMINAL.self.initial (pass to step) * TERMINAL/INITIAL -> possible next - INITIAL.self.terminal (pass to step) */ - const follow_direction = (terminal: Ray): Ray => next_pointer(terminal, () => terminal.___primitive_switch({ - [RayType.INITIAL]: Ray.directions.next, - [RayType.TERMINAL]: Ray.directions.previous, - })); + const follow_direction = (terminal: Ray): Ray => next_pointer(terminal, () => terminal.follow_direction()); const dereference = (terminal: Ray) => next_pointer(terminal, () => terminal.dereference); @@ -1025,7 +1096,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? step= Ray.___func(Ray.step).as_method(this); // TODO; Maybe replace switch with 'zip'?, What are the practical differences? - protected ___primitive_switch = (cases: SwitchCases): Ray => { + ___primitive_switch = (cases: SwitchCases TResult)>): TResult => { const _case = cases[this.type]; if (_case === undefined || _.isString(_case)) @@ -1068,6 +1139,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? get(self: Ray, p: string | symbol, receiver: any): any { + // TODO: Could return arbitrary structure (or in other method than .all?) return self.___map(ref => ref.any[p], {step}); }, From 18d2e52a83bb2f7d20d5975894e6748ced9cbdee Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sun, 21 Jan 2024 18:02:07 +0100 Subject: [PATCH 106/138] 2024/01/21 - JS tests, preparing QuickVisualizationInterface.tsx for during refactor --- src/@orbitmines/explorer/JS.spec.ts | 181 ++++++- src/@orbitmines/explorer/Ray.ts | 87 ++-- .../debug/QuickVisualizationInterface.tsx | 489 ++++++++++++++++++ src/@orbitmines/js/react/hooks/useHotkeys.ts | 73 ++- src/App.tsx | 2 + 5 files changed, 793 insertions(+), 39 deletions(-) create mode 100644 src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx diff --git a/src/@orbitmines/explorer/JS.spec.ts b/src/@orbitmines/explorer/JS.spec.ts index e6bc628..24a1fde 100644 --- a/src/@orbitmines/explorer/JS.spec.ts +++ b/src/@orbitmines/explorer/JS.spec.ts @@ -1,4 +1,4 @@ -import {JS} from "./Ray"; +import {JS, Ray, RayType} from "./Ray"; describe("JS", () => { test(".Object", () => { @@ -6,14 +6,189 @@ describe("JS", () => { a: 'b', position: [0, 1, 2], func: () => 'c' - }).as_reference(); + }); expect(ray.any.a).toBe('b'); - expect(ray.any.test).toBe(undefined); + expect(ray.any.undefinedProperty).toBe(undefined); expect(() => ray.any.undefinedFunction()).toThrow(); expect(ray.any.position).toEqual([0, 1, 2]); expect(ray.any.func()).toBe('c'); }); + test(".Boolean", () => { + const _false = JS.Boolean(false); + const _true = JS.Boolean(true); + expect(_false.any.js).toBe(false); + expect(_true.any.js).toBe(true); + expect(_false.next().any.js).toBe(true); + expect(_false.previous().is_none()).toBe(true); + + expect(_true.next().is_none()).toBe(true); + expect(_true.previous().any.js).toBe(false); + }); + test(".Bit", () => { + const _false = JS.Bit(false); + const _true = JS.Bit(true); + + expect(_false.any.js).toBe(false); + expect(_true.any.js).toBe(true); + + expect(_false.next().any.js).toBe(true); + expect(_false.previous().is_none()).toBe(true); + + expect(_true.next().is_none()).toBe(true); + expect(_true.previous().any.js).toBe(false); + }); + test(".Iterable", () => { + const iterable = JS.Iterable(['A', 'B', 'C', 'D', 'E']); + + expect(iterable.type).toBe(RayType.INITIAL); + + const A = iterable.follow(); + + expect(A.any.js).toBe('A'); + expect(A.previous().is_none()).toBe(true); + + expect(A.next().previous().any.js).toBe('A'); + expect(A.next().next().previous().previous().any.js).toBe('A'); + expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); + expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); + + expect(A.next().any.js).toBe('B'); + expect(A.next().next().any.js).toBe('C'); + expect(A.next().next().next().any.js).toBe('D'); + expect(A.next().next().next().next().any.js).toBe('E'); + + expect(A.next().next().next().next().next().is_none()).toBe(true); + + expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); + expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); + expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); + }); + test(".Generator", () => { + function* generator_function(): Generator { + yield 'A'; + yield 'B'; + yield 'C'; + yield 'D'; + yield 'E'; + } + const generator = JS.Generator(generator_function()); + + expect(generator.type).toBe(RayType.INITIAL); + + const A = generator.follow(); + + expect(A.any.js).toBe('A'); + expect(A.previous().is_none()).toBe(true); + + expect(A.next().previous().any.js).toBe('A'); + expect(A.next().next().previous().previous().any.js).toBe('A'); + expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); + expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); + + expect(A.next().any.js).toBe('B'); + expect(A.next().next().any.js).toBe('C'); + expect(A.next().next().next().any.js).toBe('D'); + expect(A.next().next().next().next().any.js).toBe('E'); + + expect(A.next().next().next().next().next().is_none()).toBe(true); + + expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); + expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); + expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); + }); + test(".Any", () => { + + // .Object + { + const ray = JS.Any({ + a: 'b', + position: [0, 1, 2], + func: () => 'c' + }); + + expect(ray.any.a).toBe('b'); + expect(ray.any.undefinedProperty).toBe(undefined); + expect(() => ray.any.undefinedFunction()).toThrow(); + expect(ray.any.position).toEqual([0, 1, 2]); + expect(ray.any.func()).toBe('c'); + } + // .Boolean + { + const _false = JS.Any(false); + const _true = JS.Any(true); + + expect(_false.any.js).toBe(false); + expect(_true.any.js).toBe(true); + + expect(_false.next().any.js).toBe(true); + expect(_false.previous().is_none()).toBe(true); + + expect(_true.next().is_none()).toBe(true); + expect(_true.previous().any.js).toBe(false); + } + // .Iterable + { + const iterable = JS.Any(['A', 'B', 'C', 'D', 'E']); + + expect(iterable.type).toBe(RayType.INITIAL); + + const A = iterable.follow(); + + expect(A.any.js).toBe('A'); + expect(A.previous().is_none()).toBe(true); + + expect(A.next().previous().any.js).toBe('A'); + expect(A.next().next().previous().previous().any.js).toBe('A'); + expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); + expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); + + expect(A.next().any.js).toBe('B'); + expect(A.next().next().any.js).toBe('C'); + expect(A.next().next().next().any.js).toBe('D'); + expect(A.next().next().next().next().any.js).toBe('E'); + + expect(A.next().next().next().next().next().is_none()).toBe(true); + + expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); + expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); + expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); + } + // .Generator + { + function* generator_function(): Generator { + yield 'A'; + yield 'B'; + yield 'C'; + yield 'D'; + yield 'E'; + } + const generator = JS.Any(generator_function()); + + expect(generator.type).toBe(RayType.INITIAL); + + const A = generator.follow(); + + expect(A.any.js).toBe('A'); + expect(A.previous().is_none()).toBe(true); + + expect(A.next().previous().any.js).toBe('A'); + expect(A.next().next().previous().previous().any.js).toBe('A'); + expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); + expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); + + expect(A.next().any.js).toBe('B'); + expect(A.next().next().any.js).toBe('C'); + expect(A.next().next().next().any.js).toBe('D'); + expect(A.next().next().next().next().any.js).toBe('E'); + + expect(A.next().next().next().next().next().is_none()).toBe(true); + + expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); + expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); + expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); + } + }); }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 99319fd..c3f9713 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -235,7 +235,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return this.___ignorantly_equivalent(vertex); } - private ___ignorantly_equivalent = (ref: Ray): Ray => { + ___ignorantly_equivalent = (ref: Ray): Ray => { ref.self.self = this.self.as_arbitrary(); this.self.self = ref.self.as_arbitrary(); @@ -369,6 +369,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } if (initial.is_boundary() && initial.dereference.is_boundary()) { + throw new NotImplementedError(); initial.as_terminal(); //.follow(Ray.directions.previous).compose(terminal.dereference); // return terminal; @@ -387,6 +388,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } if (initial.follow().type !== RayType.TERMINAL || terminal.follow(Ray.directions.previous).type !== RayType.INITIAL) { + throw new NotImplementedError(); initial.dereference.push_back(terminal.dereference); // TODO: NON-PUSH-BACK VARIANT? (Just local splits?) return terminal; // throw new PreventsImplementationBug(` @@ -591,6 +593,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? static directions = { next: (ref: Ray) => ref.self.terminal.as_reference(), previous: (ref: Ray) => ref.self.initial.as_reference(), + none: (ref: Ray) => ref, // Note that "None" is necessarily inconsistent } // TODO: Nicer one? ; Differentiate between ".next" and just "follow the pointer" ? @@ -1206,6 +1209,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // return self.as_arbitrary(); }, set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { + // TODO: + // self._dirty_store[p] = JS.is_function(newValue) ? newValue(self._dirty_store[p]) : newValue; // throw new NotImplementedError(); self._dirty_store[p] = newValue; @@ -1261,11 +1266,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? if (memory) { if (!target_ray.any.traversed) { - Interface.___any.rays.push(target); + Interface.any.rays.compose(target); target_ray.any.traversed = true; } } else { - Interface.___any.rays = [target]; + Interface.any.rays = [target]; } return target; @@ -1286,7 +1291,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? this.any.scale ?? (this.is_none() ? 1.5 : 1.5), color: - (Ray.is_orbit(Interface.___any.selection.self, this.self) && Interface.___any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) + (Ray.is_orbit(Interface.any.selection.self, this.self) && Interface.any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) : ( this.any.color ?? (this.is_none() ? 'red' : { @@ -1534,12 +1539,13 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? */ export namespace JS { export const Boolean = (boolean: boolean): Ray => { + // TODO: Could be superpose structure instead of length 2; // |-false->-true-| (could of course also be reversed) - const _false = Ray.vertex().o({ js: false }); - const _true = Ray.vertex().o({ js: true }); + const _false = Ray.vertex().o({ js: false }).as_reference(); + const _true = Ray.vertex().o({ js: true }).as_reference(); _false.compose(_true); - return (boolean ? _true : _false).as_reference(); + return (boolean ? _true : _false); } // export const bit = (bit?: boolean): Arbitrary> => permutation(bit ? 1 : 0, 2); export const Bit = Boolean; @@ -1549,44 +1555,58 @@ export namespace JS { export const Iterator = (iterator: Iterator): Ray => { // [ |--] - const next = (initial: Ray): Ray => { + const next = (previous: Ray, first: boolean = false): Ray => { const iterator_result = iterator.next(); const is_terminal = iterator_result.done === true; + // Clear the terminal function attached to the Iterator. + // TODO: In case of 'is_terminal = true': Could also leave this be, in case JavaScript allows for adding stuff to the iterator even after .done === true; + previous.self.terminal = previous.self.___empty_terminal(); + if (is_terminal) { // We're done, this is the end of the iterator - // vertex: could have something at the vertex which defines the "end of the iterator" - but we don't here. - const terminal = new Ray({ - initial: () => initial - }); - // initial.compose(() => terminal.as_reference()); + return Ray.None(); + } + + const current = Ray + .vertex(() => JS.Any(iterator_result.value)) + .o({js: iterator_result.value}) + .as_reference(); + + // Move the iterator to the terminal. + current.self.terminal = () => next(current); + + if (first) { + // Move the iterator's terminal to current. + ray_iterator.self.terminal = () => current.self; - // if (initial.is_some()) - // initial.terminal = () => terminal; // TODO REPEAT FROM BELOW + current.self.initial = () => ray_iterator.self; - return terminal; + return current; // Answer to INITIAL.terminal is a VERTEX. } - const current: Ray = new Ray({ - // initial: () => new Ray(), - initial: () => initial, - vertex: () => JS.Any(iterator_result.value), - terminal: () => next(current) - }).o({js: iterator_result.value}); + // TODO: This is just compose, but without .type checks.. ; FIX ON COMPOSE END for is_reference etc.. + if (previous.follow().type !== RayType.TERMINAL) + throw new PreventsImplementationBug(); + if (current.follow(Ray.directions.previous).type !== RayType.INITIAL) + throw new PreventsImplementationBug(); - // initial.compose(() => current.as_reference()); - if (initial.is_some()) - initial.terminal = () => current; + previous.follow().equivalent(current.follow(Ray.directions.previous)); + // TODO: + // previous.compose(current); - return current; + return current.self.initial; // Answer to VERTEX.terminal is an INITIAL. } - const ray_iterator = Ray.None().o({ js: iterator }); - ray_iterator.terminal = () => next(ray_iterator); + const ray_iterator: Ray = new Ray({ + vertex: Ray.None, + terminal: () => next(ray_iterator, true), + }) + .o({ js: iterator }) + .as_reference(); - // This indicates we're passing a reference, since traversal logic will be defined at its vertex - what it's defining. - return ray_iterator.as_reference(); + return ray_iterator; } export const Generator = (generator: Generator): Ray => JS.Iterable(generator); @@ -1605,7 +1625,8 @@ export namespace JS { throw new NotImplementedError(); } - export const Object = (object: object): Ray => Ray.vertex().o(object); + // TODO + export const Object = (object: object): Ray => Ray.vertex().o(object).as_reference(); export const Any = (any: any): Ray => { if (any === null || any === undefined) return JS.Any(any); @@ -1617,13 +1638,13 @@ export namespace JS { // TODO // return JS.Any(any); - return Ray.vertex().o({js: any}); + return Ray.vertex().o({js: any}).as_reference(); } export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); export const is_number = (_object: any): _object is number => _.isNumber(_object); export const is_object = (_object: any): _object is object => _.isObject(_object); - export const is_iterable = (_object: any): _object is Iterable => Symbol.iterator in Object(_object); + export const is_iterable = (_object: any): _object is Iterable => Symbol.iterator in Object(_object) && is_function(_object[Symbol.iterator]); export const is_async_iterable = (_object: any): _object is AsyncIterable => Symbol.asyncIterator in Object(_object); export const is_array = (_object: any): _object is T[] => _.isArray(_object); export const is_async = (_object: any) => _.has(_object, 'then') && is_function(_.get(_object, 'then')); // TODO, Just an ugly check diff --git a/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx b/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx new file mode 100644 index 0000000..6b11cd0 --- /dev/null +++ b/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx @@ -0,0 +1,489 @@ +import React, {useRef, useState} from "react"; +import IEventListener from "../../js/react/IEventListener"; +import {VisualizationCanvas} from "../Visualization"; +import { + _Continuation, + _Vertex, + add, + add_, + AutoVertex, + circle, + InterfaceOptions, + Line, + torus +} from "../OrbitMinesExplorer"; +import {HotkeyEventOptions, useHotkeys} from "../../js/react/hooks/useHotkeys"; +import {Implementation, Ray, RayType} from "../Ray"; +import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; +import _ from "lodash"; +import {useThree} from "@react-three/fiber"; +import {StatsPanels} from "./DebugCanvas"; + +const ___index = (ray: Ray): number => { + switch (ray.type) { + case RayType.REFERENCE: + return ray.___any.index ?? 0; + case RayType.INITIAL: + return ray.follow().___any.index ?? 0; + case RayType.TERMINAL: + return ray.follow(Ray.directions.previous).___any.index ?? 0; + case RayType.VERTEX: + return ray.___any.index ?? 0; + } +} + +export const Render2 = ({ ray, Interface, show = { initial: true, terminal: true } }: { ray: Ray, Interface: Ray, index: number, show?: { initial: boolean, terminal: boolean } }) => { + const index = ___index(ray); + let added = [15 * index, 60 * index, 0]; + + const initial: Required = ray.follow(Ray.directions.previous).render_options(Interface); + initial.position = add_(initial.position, added); + const vertex: Required = ray.render_options(Interface); + vertex.position = add_(vertex.position, added); + const terminal: Required = ray.follow().render_options(Interface); + terminal.position = add_(terminal.position, added); + + switch (ray.type) { + case RayType.REFERENCE: { + return <_Vertex position={vertex.position} rotation={[0, 0, Math.PI / 2]} scale={vertex.scale / 2} + color="#555555"/>; + } + case RayType.VERTEX: { + return + + <_Vertex {...vertex} /> + + + } + case RayType.INITIAL: { + return + + + <_Continuation {...vertex} + position={add_(vertex.position, !show.initial && ray.type === RayType.INITIAL ? [-15, -15, 0] : [0, 0, 0])}/> + + } + case RayType.TERMINAL: { + return + + <_Continuation {...vertex} + position={add_(vertex.position, !show.terminal && ray.type === RayType.TERMINAL ? [15, 15, 0] : [0, 0, 0])}/> + + } + default: { + return + } + } + switch (ray.type) { + case RayType.REFERENCE: + return <_Vertex position={vertex.position} rotation={[0, 0, Math.PI / 2]} scale={vertex.scale / 2} + color="#555555"/> + case RayType.INITIAL: { + const diff = [-15, -15, 0]; + + return + {!show.initial ? : + + + + + + } + + + + + + + + <_Continuation {...vertex} position={add_(vertex.position, !show.initial && ray.type === RayType.INITIAL ? [-15, -15, 0] : [0, 0, 0])} /> + + + {!show.initial ? : + + <_Continuation {...vertex} position={add_(vertex.position, diff)} color="#FF5555"/> + <_Continuation {...vertex} position={add_(vertex.position, diff, [-30, 0, 0])} scale={vertex.scale / 3 * 2} + color="#AA0000"/> + } + + } + case RayType.TERMINAL: { + const diff = [15, 15, 0]; + + return + {!show.terminal ? : + + + + + + + + } + + + + + + <_Continuation {...vertex} position={add_(vertex.position, !show.terminal && ray.type === RayType.TERMINAL ? [15, 15, 0] : [0, 0, 0])} /> + + + {!show.terminal ? : + + <_Continuation {...vertex} position={add_(vertex.position, diff)} color="#5555FF" /> + <_Continuation {...vertex} position={add_(vertex.position, diff, [30, 0, 0])} scale={vertex.scale / 3 * 2} color="#AA0000"/> + } + + } + } +} + +export const QuickVisualizationInterface = ({scale = 1.5}: InterfaceOptions) => { + const ref = useRef(); + const hotkeyConfig = useHotkeys(); + + const { + gl: renderer, + camera, + scene, + raycaster + } = useThree(); + + const space_between = 20 * scale; + + const [Interface] = useState(Ray.vertex().o({ + selection: + // The things selected + Ray.None() + // Our cursor + .as_reference().o({ + position: [0, 0, 0], + scale, + rotation: [0, 0, Math.PI / 6 ], + color: '#555555' + }) + // A reference to our cursor + .as_reference(), + rays: [] as Ray[], + stats: false, + cursor: { + tick: false + }, + add: (ray: Ray) => { + (Interface.any.selection as Ray).self.self = ray.self.as_arbitrary(); + Interface.any.rays.push(...[ray.follow(Ray.directions.previous), ray, ray.follow()]); + }, + controls: { + hotkeys: [ + { + + combo: ["space"], global: true, label: "", onKeyDown: () => { + const { selection, rays } = Interface.any; + + if (selection.self.is_none()) { + console.log('hi'); + + Interface.any.add( + Ray.vertex().o2({ + initial: { position: [-space_between, 0, 0], scale, color: 'orange' }, + vertex: { index: 0, position: [0, 0, 0], scale, color: 'orange' }, + terminal: { position: [space_between, 0, 0 ], scale, color: 'orange' }, + }).as_reference() + ); + + } + } + }, + { + combo: [ + "w", + "a", + "s", + "d" + ], global: true, label: "", preventDefault: true, onKeyDown: (event: any, { pressed }: HotkeyEventOptions) => { + const selection = Interface.any.selection as Ray; + + // TODO These should be Rays at some point + const directions = [ + [["a"], ["d"]], // TODO These superpositions on initial/terminal side + [["s"], ["w"]], + // TODO Then expand these to any-dimensional + ]; + + const isFollowing = directions.map( + ([initial, terminal]) => { + const toInitial = initial.some(option => pressed.includes(option)); + const toTerminal = terminal.some(option => pressed.includes(option)); + + if (toInitial === toTerminal) + return 0; + + return toInitial ? -1 : 1; + } + ); + + // TODO: .all(), which includes the reference?? ; since selection can be arbitrary structure too. + // selection.any.position = add(selection.any.position, [ + // space_between * isFollowing[0], + // space_between * isFollowing[1], + // 0 + // ]); + // selection.all().position = (position: [number, number, number]) => add(position, [ + // space_between * isFollowing[0], // TODO These selections automatic + // space_between * isFollowing[1], + // 0 + // ]); + // selection.self.any.position = add(selection.self.any.position, [ + // (space_between / 2) * isFollowing[0], // TODO These selections automatic + // (space_between / 2) * isFollowing[1], + // 0 + // ]); + if (isFollowing[0] !== 0) { + // TODO: Should be on here compose(terminal).all().position = + const position = Interface.any.selection.dereference.any.position; + const to_add = [(space_between * 2) * isFollowing[0], 0, 0]; + + const ref = Ray.vertex().o2({ + initial: { position: add_(position, to_add, [-space_between, 0, 0]), scale, color: 'orange' }, + vertex: { index: 0, position: add_(position, to_add, [0, 0, 0]), scale, color: 'orange' }, + terminal: { position: add_(position, to_add, [space_between, 0, 0 ]), scale, color: 'orange' }, + }).as_reference(); + + const [initial, terminal] = isFollowing[0] === -1 ? + [ref, selection.dereference,] : [selection.dereference, ref]; + + initial.compose(terminal); + + Interface.any.add(ref); + } + } + }, + { + combo: [ + "arrowright", + "arrowleft", + "arrowup", + "arrowdown" + ], global: true, label: "", preventDefault: true, onKeyDown: (event: any, { pressed }: HotkeyEventOptions) => { + const selection = Interface.any.selection as Ray; + + // TODO These should be Rays at some point + const directions = [ + [["arrowleft"], ["arrowright"]], // TODO These superpositions on initial/terminal side + [["arrowdown"], ["arrowup"]], + // TODO Then expand these to any-dimensional + ]; + + const isFollowing = directions.map( + ([initial, terminal]) => { + const toInitial = initial.some(option => pressed.includes(option)); + const toTerminal = terminal.some(option => pressed.includes(option)); + + if (toInitial === toTerminal) + return 0; + + return toInitial ? -1 : 1; + } + ); + + // TODO: .all(), which includes the reference?? ; since selection can be arbitrary structure too. + // selection.any.position = add(selection.any.position, [ + // space_between * isFollowing[0], + // space_between * isFollowing[1], + // 0 + // ]); + // selection.all().position = (position: [number, number, number]) => add(position, [ + // space_between * isFollowing[0], // TODO These selections automatic + // space_between * isFollowing[1], + // 0 + // ]); + selection.self.any.position = add(selection.self.any.position, [ + (space_between / 2) * isFollowing[0], // TODO These selections automatic + (space_between / 2) * isFollowing[1], + 0 + ]); + } + }, + { + combo: [ + "ctrl + arrowright", + "ctrl + arrowleft", + "ctrl + arrowup", + "ctrl + arrowdown" + ], global: true, label: "", preventDefault: true, onKeyDown: (event: any, { pressed }: HotkeyEventOptions) => { + const { selection, rays } = Interface.any; + + // TODO These should be Rays at some point + const directions = [ + [["arrowleft"], ["arrowright"]], // TODO These superpositions on initial/terminal side + [["arrowdown"], ["arrowup"]], + // TODO Then expand these to any-dimensional + ]; + const isFollowing = directions.map( + ([initial, terminal]): Implementation => { + const toInitial = initial.some(option => pressed.includes(option)); + const toTerminal = terminal.some(option => pressed.includes(option)); + + if (toInitial === toTerminal) + return Ray.directions.none; + + return toInitial ? Ray.directions.previous : Ray.directions.next; + } + ); + + // TODO ; ANY NUMBER/structure CURSOR + const next = (Interface.any.selection as Ray).dereference.follow(isFollowing[0]); + if (next.self.is_some()) { + console.log('a'); + (Interface.any.selection as Ray).self.self = next.self.as_arbitrary(); + } + + console.log(isFollowing) + + // selection.all().position = (position: [number, number, number]) => add(position, [ + // space_between * isFollowing[0], // TODO These selections automatic + // space_between * isFollowing[1], + // 0 + // ]); + } + }, + { + combo: "/", global: true, label: "", preventDefault: true, onKeyDown: () => { + console.log(Interface.any.rays.map((ray: Ray) => ray.render_options(Interface))) + // console.log('---------') + // console.log(`Debugging: ${Interface.any.selection.self.label} (type=${Interface.any.selection.type})`) + // console.log(`rays.length at pos=[${Interface.any.selection.render_options(Interface).position}]: ${Interface.any.rays.filter((ray: Ray) => + // _.isEqual( + // Interface.any.selection.render_options.position, + // ray.render_options(Interface).position + // ) + // ).length} / ${Interface.any.rays.length}`) + // console.log('ref', Interface.any.selection) + // console.log('ref.self', Interface.any.selection.self) + // + // const debug: DebugResult = {}; + // Interface.any.selection.self.debug(debug); + // console.log('ref.debug', debug); + // Interface.any.rays.forEach((ray: Ray) => ray.debug(debug)); + // console.log('rays.debug', debug); + + } + }, + { + combo: "f3", global: true, label: "Show stats Panel", preventDefault: true, onKeyDown: (e) => { + e.preventDefault(); + Interface.any.stats = !Interface.any.stats; + } + }, + ] as HotkeyConfig[] + } + }).as_reference()); + + // useEffect(() => { + // TODO: Eventually goes over maximum size of react-debug callstack when updates each frame like this. + hotkeyConfig.set(...Interface.any.controls.hotkeys); + // }, [Interface.any.controls.___any.hotkeys]); + + const index = ___index(Interface.any.selection); + const added = [15 * index, 60 * (index + 1), 0]; + + return <> + {Interface.any.stats ? : <>} + + + + {/*{Interface.any.rays.map((ray: Ray) => )}*/} + + {Interface.any.rays.map((ray: Ray) => )} + + {/**/} + {/* */} + {/* */} + {/* {Interface.any.rays.___map((ray: Ray, index: number) => )}*/} + {/* */} + {/**/} + + {/**/} + {/* */} + {/* */} + {/* {Interface.any.rays.___map((ray: Ray, index: number) => )}*/} + {/* */} + {/**/} + +} + +const QuickVisualizationCanvas = ( + { + listeners = [], + }: { + listeners?: IEventListener[], + } +) => { + const listener: IEventListener = { + + } + + return
+ {/**/} + {/* */} + {/* */} + {/**/} + + + + +
+} + +export const QuickVisualizationExplorer = ( + { + listeners = [], + }: { + listeners?: IEventListener[], + } +) => { + + const listener: IEventListener = {} + + return +} + +export default QuickVisualizationCanvas; \ No newline at end of file diff --git a/src/@orbitmines/js/react/hooks/useHotkeys.ts b/src/@orbitmines/js/react/hooks/useHotkeys.ts index d1fd08e..b5990ec 100755 --- a/src/@orbitmines/js/react/hooks/useHotkeys.ts +++ b/src/@orbitmines/js/react/hooks/useHotkeys.ts @@ -4,7 +4,21 @@ import {useHotkeys as useBlueprintJSHotkeys} from '@blueprintjs/core'; import {useState} from "react"; import _ from "lodash"; -export type HotkeyConfigMod = HotkeyConfig & { combo: string | string[] } +export type PressedKeys = string[]; +export type HotkeyEventOptions = { pressed: PressedKeys }; +export type HotkeyConfigMod = HotkeyConfig & { + combo: string | string[], + + /** + * `keydown` event handler. + */ + onKeyDown?(e: KeyboardEvent, options: HotkeyEventOptions): any; + + /** + * `keyup` event handler. + */ + onKeyUp?(e: KeyboardEvent, options: HotkeyEventOptions): any; +} export const HOTKEYS_MODULE = 'hotkeys'; @@ -13,6 +27,7 @@ export type IHotkeysModule = IModule & { add: (...hotkeys: HotkeyConfigMod[]) => void, set: (...hotkeys: HotkeyConfigMod[]) => void, all: () => HotkeyConfigMod[], + currentlyPressed: () => string[], } export const useHotkeys = (): IHotkeysModule => useModule(HOTKEYS_MODULE) as IHotkeysModule; @@ -20,6 +35,11 @@ export const useHotkeys = (): IHotkeysModule => useModule(HOTKEYS_MODULE) as IHo export const useHotkeysModule = (...initialHotkeys: HotkeyConfigMod[]): IHotkeysModule => { const [hotkeys, setHotkeys] = useState(initialHotkeys ?? []); + /** + * TODO: This is not perfect, out of focus ; skipping window, that kind of thing.. ; async calls to this ; delay ... + */ + const [currentlyPressed, setCurrentlyPressed] = useState([]); + // Hotkeys: https://blueprintjs.com/docs/#core/hooks/use-hotkeys const { handleKeyDown: onKeyDown, handleKeyUp: onKeyUp } = useBlueprintJSHotkeys(hotkeys, { showDialogKeyCombo: "?", @@ -28,9 +48,55 @@ export const useHotkeysModule = (...initialHotkeys: HotkeyConfigMod[]): IHotkeys const setHotKeysMod = (hotkeys: HotkeyConfigMod[]): void => setHotkeys( hotkeys.flatMap(hotkey => !_.isArray(hotkey.combo) ? hotkey : hotkey.combo.map( - combo => {...hotkey, combo} + combo => {...hotkey, combo,} ) - ) + ).map(hotkey => { + ...hotkey, + + onKeyDown: (event) => { + const pressed = _.compact(_.uniq( + [ + ...currentlyPressed, + event.key.toLowerCase(), + event.metaKey ? 'meta' : undefined, + event.ctrlKey ? 'ctrl' : undefined, + event.altKey ? 'alt' : undefined, + event.shiftKey ? 'shift' : undefined, + ] + )); + + setCurrentlyPressed(previous => _.compact(_.uniq( + [ + ...previous, + event.key.toLowerCase(), + event.metaKey ? 'meta' : undefined, + event.ctrlKey ? 'ctrl' : undefined, + event.altKey ? 'alt' : undefined, + event.shiftKey ? 'shift' : undefined, + ] + ))); + + if (hotkey.onKeyDown) { + hotkey.onKeyDown(event, { pressed }); + } + }, + onKeyUp: (event) => { + const exclude = _.compact(_.uniq([ + event.key.toLowerCase(), + !event.metaKey ? 'meta' : undefined, + !event.ctrlKey ? 'ctrl' : undefined, + !event.altKey ? 'alt' : undefined, + !event.shiftKey ? 'shift' : undefined, + ])); + const pressed = [...currentlyPressed.filter(key => !exclude.includes(key))]; + + setCurrentlyPressed(previous => [...previous.filter(key => !exclude.includes(key))]); + + if (hotkey.onKeyUp) { + hotkey.onKeyUp(event, { pressed }); + } + } + }) ) @@ -41,6 +107,7 @@ export const useHotkeysModule = (...initialHotkeys: HotkeyConfigMod[]): IHotkeys add: (...added: HotkeyConfigMod[]) => setHotKeysMod([...hotkeys, ...added]), set: (...hotkeys: HotkeyConfigMod[]) => setHotKeysMod([...hotkeys]), all: () => hotkeys, + currentlyPressed: () => currentlyPressed, onKeyDown, onKeyUp diff --git a/src/App.tsx b/src/App.tsx index 49bd462..c63fdcb 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,6 +15,7 @@ import Icons from "./lib/layout/experimental-designs/Icons"; import {ThumbnailPage} from "./lib/paper/Paper"; import {ChypExplorer} from "./@orbitmines/external/chyp/ChypCanvas"; import {DebugExplorer} from "./@orbitmines/explorer/debug/DebugCanvas"; +import {QuickVisualizationExplorer} from "./@orbitmines/explorer/debug/QuickVisualizationInterface"; export const Router = () => { @@ -28,6 +29,7 @@ export const Router = () => { } /> + } /> } /> {/*} />*/} From 9322d41fdbb33f30a7aaedffef201afbed7f4726 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sun, 21 Jan 2024 19:32:43 +0100 Subject: [PATCH 107/138] 2024/01/21 - Moving function implementation to JS.ts --- src/@orbitmines/explorer/JS.spec.ts | 22 ++- src/@orbitmines/explorer/JS.ts | 221 +++++++++++++++++++++ src/@orbitmines/explorer/Ray.spec.ts | 62 +++--- src/@orbitmines/explorer/Ray.ts | 282 ++++----------------------- 4 files changed, 307 insertions(+), 280 deletions(-) create mode 100644 src/@orbitmines/explorer/JS.ts diff --git a/src/@orbitmines/explorer/JS.spec.ts b/src/@orbitmines/explorer/JS.spec.ts index 24a1fde..95d567b 100644 --- a/src/@orbitmines/explorer/JS.spec.ts +++ b/src/@orbitmines/explorer/JS.spec.ts @@ -1,6 +1,26 @@ -import {JS, Ray, RayType} from "./Ray"; +import {Ray, RayType} from "./Ray"; +import JS from "./JS"; describe("JS", () => { + test(".Function.Ref(ref)", () => { + const method = JS.Function.Ref((ref): Ray => new Ray({ + initial: ref.self.initial.as_arbitrary(), + terminal: ref.self.terminal.as_arbitrary() + }).o({ js: ref.type })).as_method; + + expect(method(Ray.vertex().as_reference().as_reference())().any.js).toBe(RayType.REFERENCE); + expect(method(Ray.vertex().as_reference())().any.js).toBe(RayType.VERTEX); + expect(method(Ray.initial().as_reference())().any.js).toBe(RayType.INITIAL); + expect(method(Ray.terminal().as_reference())().any.js).toBe(RayType.TERMINAL); + + const a = Ray.vertex().o({ js: 'A'}).as_reference(); + const b = Ray.vertex().o({ js: 'B'}).as_reference(); + + // TODO What about method(a)(b)(c)... :thinking: + expect(method(a)(b).initial.any.js).toBe('A'); + expect(method(a)(b).terminal.any.js).toBe('B'); + expect(method(a)(b).type).toBe(RayType.VERTEX); + }); test(".Object", () => { const ray = JS.Object({ a: 'b', diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts new file mode 100644 index 0000000..0528879 --- /dev/null +++ b/src/@orbitmines/explorer/JS.ts @@ -0,0 +1,221 @@ +import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; +import _ from "lodash"; +import {AbstractDirectionality, Ray, RayType} from "./Ray"; + +/** + * + * Important to remember this is just one particular structure to which it can be mapped, there are probably many (TODO infinitely?) others. + * + * Not to be considered as a perfect mapping of JavaScript functionality - merely a practical one. + */ +namespace JS { + export type ParameterlessFunction = () => T; + export type ParameterlessConstructor = new () => T; + export type Constructor = new (...args: any[]) => T; + export type Implementation = (ref: T) => T; + + export type Arbitrary = ParameterlessFunction; + + export type Recursive = (T | Recursive)[]; + export type Method = (...other: Recursive) => T; + + /** + * This allows automatic conversion between "JavaScript functions/.../generators" and Rays. + * + * TODO: Is there some equivalent of this in computer science??? category theory?? + */ + export class Function = Ray> { // TODO: Ray could extend Function + + private readonly step: Implementation; + + constructor(step: JS.Implementation) { + this.step = step; + } + + static Any = = Ray>(...args: any[]): Function => { + throw new NotImplementedError(); + } + + /** + * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] + */ + static Ref = = Ray>(impl: (ref: T) => T): Function => { + return new Function(impl); + } + + static Impl = = Ray>(impl: (initial: T, terminal: T) => T): Function => { + return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); + } + static IgnorantOfInitial = = Ray>(impl: (terminal: T) => T): Function => Function.Impl((_, terminal) => impl(terminal)); + static IgnorantOfTerminal = = Ray>(impl: (initial: T) => T): Function => Function.Impl((initial, _) => impl(initial)); + static Ignorant = = Ray>(impl: ParameterlessFunction): Function => Function.Impl(impl); + + /** + * Constructs a class method accepting arbitrary structure. + * + * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = [[a1, [[[a2]]], [[[[]]], []]], b, [[[]], [], [c]]].compose = ... + */ + as_method = (ref: T): Method => ((...any: Recursive): T => { + if (any === undefined || any.length === 0) + return this.step(ref); + + // TODO: This can be much better... + const first = (recursive?: Recursive): T | undefined => { + if (recursive === undefined) return; + // if (_.isObject(recursive)) return recursive as unknown as Ray; + + for (let r of recursive) { + if (r === undefined) continue; + if (_.isObject(r)) return r as unknown as T; + + // if (r instanceof Ray) + // throw new PreventsImplementationBug(); + + // @ts-ignore + const _first = first(r); + if (_first) + return _first; + } + } + + const _first = first(any); + + if (_first === undefined) + return this.step(ref); + + const pointer = (new Ray({ + // @ts-ignore + initial: () => ref, + // @ts-ignore + terminal: () => _first + })) as unknown as T; + + return this.step(pointer); + + // TODO: ANY CASE + // if (any.length === 1) { + // } + }) + + as_ray = (): Ray => { + throw new NotImplementedError(); + } + + as_generator = (): Generator => { + throw new NotImplementedError(); + } + + } + + export const Boolean = (boolean: boolean): Ray => { + // TODO: Could be superpose structure instead of length 2; + // |-false->-true-| (could of course also be reversed) + const _false = Ray.vertex().o({ js: false }).as_reference(); + const _true = Ray.vertex().o({ js: true }).as_reference(); + _false.compose(_true); + + return (boolean ? _true : _false); + } + // export const bit = (bit?: boolean): Arbitrary> => permutation(bit ? 1 : 0, 2); + export const Bit = Boolean; + + export const Iterable = (iterable: Iterable): Ray => JS.Iterator(iterable[Symbol.iterator]()); + + export const Iterator = (iterator: Iterator): Ray => { + // [ |--] + + const next = (previous: Ray, first: boolean = false): Ray => { + const iterator_result = iterator.next(); + const is_terminal = iterator_result.done === true; + + // Clear the terminal function attached to the Iterator. + // TODO: In case of 'is_terminal = true': Could also leave this be, in case JavaScript allows for adding stuff to the iterator even after .done === true; + previous.self.terminal = previous.self.___empty_terminal(); + + if (is_terminal) { + // We're done, this is the end of the iterator + + return Ray.None(); + } + + const current = Ray + .vertex(() => JS.Any(iterator_result.value)) + .o({js: iterator_result.value}) + .as_reference(); + + // Move the iterator to the terminal. + current.self.terminal = () => next(current); + + if (first) { + // Move the iterator's terminal to current. + ray_iterator.self.terminal = () => current.self; + + current.self.initial = () => ray_iterator.self; + + return current; // Answer to INITIAL.terminal is a VERTEX. + } + + // TODO: This is just compose, but without .type checks.. ; FIX ON COMPOSE END for is_reference etc.. + if (previous.follow().type !== RayType.TERMINAL) + throw new PreventsImplementationBug(); + if (current.follow(Ray.directions.previous).type !== RayType.INITIAL) + throw new PreventsImplementationBug(); + + previous.follow().equivalent(current.follow(Ray.directions.previous)); + // TODO: + // previous.compose(current); + + return current.self.initial; // Answer to VERTEX.terminal is an INITIAL. + } + + const ray_iterator: Ray = new Ray({ + vertex: Ray.None, + terminal: () => next(ray_iterator, true), + }) + .o({ js: iterator }) + .as_reference(); + + return ray_iterator; + } + + export const Generator = (generator: Generator): Ray => JS.Iterable(generator); + + // TODO Could have parallel threads in general. + // export const AsyncGenerator = (generator: AsyncGenerator): Ray => { + // // [ |--] + // return JS.Iterable(generator); + // } + + export const Number = (number: number): Ray => { + throw new NotImplementedError(); + } + + // TODO + export const Object = (object: object): Ray => Ray.vertex().o(object).as_reference(); + + export const Any = (any: any): Ray => { + if (any === null || any === undefined) return JS.Any(any); + if (JS.is_boolean(any)) return JS.Boolean(any); + if (JS.is_number(any)) return JS.Number(any); + if (JS.is_iterable(any)) return JS.Iterable(any); // || is_array(any)) + if (JS.is_function(any)) return JS.Function.Any(any).as_ray(); + if (JS.is_object(any)) return JS.Object(any); + + // TODO + // return JS.Any(any); + return Ray.vertex().o({js: any}).as_reference(); + } + + export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); + export const is_number = (_object: any): _object is number => _.isNumber(_object); + export const is_object = (_object: any): _object is object => _.isObject(_object); + export const is_iterable = (_object: any): _object is Iterable => Symbol.iterator in Object(_object) && is_function(_object[Symbol.iterator]); + export const is_async_iterable = (_object: any): _object is AsyncIterable => Symbol.asyncIterator in Object(_object); + export const is_array = (_object: any): _object is T[] => _.isArray(_object); + export const is_async = (_object: any) => _.has(_object, 'then') && is_function(_.get(_object, 'then')); // TODO, Just an ugly check + + export const is_error = (_object: any): _object is Error => _.isError(_object); + export const is_function = (_object: any): _object is ((...args: any[]) => any) => _.isFunction(_object); +} + +export default JS; \ No newline at end of file diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 6435e6a..4cf0cf9 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -1,25 +1,6 @@ import {Ray, RayType} from "./Ray"; describe("Ray", () => { - test(".___func(ref)", () => { - const method = Ray.___func((ref: Ray): Ray => new Ray({ - initial: ref.self.initial.as_arbitrary(), - terminal: ref.self.terminal.as_arbitrary() - }).o({ js: ref.type })).as_method; - - expect(method(Ray.vertex().as_reference().as_reference())().any.js).toBe(RayType.REFERENCE); - expect(method(Ray.vertex().as_reference())().any.js).toBe(RayType.VERTEX); - expect(method(Ray.initial().as_reference())().any.js).toBe(RayType.INITIAL); - expect(method(Ray.terminal().as_reference())().any.js).toBe(RayType.TERMINAL); - - const a = Ray.vertex().o({ js: 'A'}).as_reference(); - const b = Ray.vertex().o({ js: 'B'}).as_reference(); - - // TODO What about method(a)(b)(c)... :thinking: - expect(method(a)(b).initial.any.js).toBe('A'); - expect(method(a)(b).terminal.any.js).toBe('B'); - expect(method(a)(b).type).toBe(RayType.VERTEX); - }); test("[A, B, C].copy", () => { const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); @@ -1424,27 +1405,28 @@ describe("Ray", () => { .as_reference().any.js ).toBe('B'); }); - test("[.vertex.#, .vertex.#].#.compose", () => { - let A = Ray.vertex().o({ js: 'A' }).as_reference(); - let B = Ray.vertex().o({ js: 'B' }).as_reference(); - - B = new Ray({ - initial: A.as_arbitrary(), - terminal: B.as_arbitrary() - }).as_reference().compose(); - - expect(B.type).toBe(RayType.VERTEX); - expect(B.any.js).toBe('B'); - expect(B.self - .initial.self.initial - .as_reference().any.js - ).toBe('A'); - expect(B.self - .initial.self.initial - .terminal.self.terminal - .as_reference().any.js - ).toBe('B'); - }); + // TODO: .compose(), should take everything at the vertex instead. + // test("[.vertex.#, .vertex.#].#.compose", () => { + // let A = Ray.vertex().o({ js: 'A' }).as_reference(); + // let B = Ray.vertex().o({ js: 'B' }).as_reference(); + // + // B = new Ray({ + // initial: A.as_arbitrary(), + // terminal: B.as_arbitrary() + // }).as_reference().compose(); + // + // expect(B.type).toBe(RayType.VERTEX); + // expect(B.any.js).toBe('B'); + // expect(B.self + // .initial.self.initial + // .as_reference().any.js + // ).toBe('A'); + // expect(B.self + // .initial.self.initial + // .terminal.self.terminal + // .as_reference().any.js + // ).toBe('B'); + // }); // test(".vertex.#.debug", () => { TODO // const a = Ray.vertex().as_reference(); // const b = Ray.vertex().as_reference(); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index c3f9713..950ef08 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,6 +1,7 @@ import _ from "lodash"; import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; +import JS from "./JS"; // TODO: SHOULDNT CLASSIFY THESE? (And incorporate in Ray??) export enum RayType { @@ -13,16 +14,6 @@ export enum RayType { export type Boundary = RayType.INITIAL | RayType.TERMINAL; const opposite = (boundary: Boundary): Boundary => boundary === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL; -export type ParameterlessFunction = () => T; -export type Arbitrary = (...args: any[]) => T; -export type Constructor = new (...args: any[]) => T; -export type ParameterlessConstructor = new () => T; - -// TODO: Merge with Arbitrary. -export type Recursive = (T | Recursive)[]; -export type Method = (...other: Recursive) => T; -export type ArbitraryMethod = (ref: T) => Method; - export type SwitchCases< T = Ray, SwitchCase extends string | symbol | number = RayType, @@ -31,8 +22,6 @@ export type SwitchCases< [TCase in SwitchCase]?: TResult } -export type Implementation = (ref: T) => T; - /** * https://en.wikipedia.org/wiki/Homoiconicity */ @@ -42,7 +31,11 @@ export interface PossiblyHomoiconic> { as_reference: () => T } -export interface AbstractDirectionality { initial: Arbitrary, vertex: Arbitrary, terminal: Arbitrary } +export interface AbstractDirectionality { + get initial(): T, + get vertex(): T, + get terminal(): T +} // TODO: better debug export type DebugResult = { [label: string]: DebugRay } @@ -92,6 +85,7 @@ export type DebugRay = { */ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? implements + AbstractDirectionality, PossiblyHomoiconic, AsyncIterable, @@ -101,13 +95,17 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? { // TODO: Could make a case that setting the terminal is more of a map, defaulting/first checking the terminal before additional functionality is mapped over that. - protected _initial: Arbitrary; get initial(): Ray { return this._initial(); } set initial(initial: Arbitrary) { this._initial = initial; } - protected _vertex: Arbitrary; get vertex(): Ray { return this._vertex(); } set vertex(vertex: Arbitrary) { this._vertex = vertex; } - protected _terminal: Arbitrary; get terminal(): Ray { return this._terminal(); } set terminal(terminal: Arbitrary) { this._terminal = terminal; } + protected _initial: JS.Arbitrary; get initial(): Ray { return this._initial(); } set initial(initial: JS.Arbitrary) { this._initial = initial; } + protected _vertex: JS.Arbitrary; get vertex(): Ray { return this._vertex(); } set vertex(vertex: JS.Arbitrary) { this._vertex = vertex; } + protected _terminal: JS.Arbitrary; get terminal(): Ray { return this._terminal(); } set terminal(terminal: JS.Arbitrary) { this._terminal = terminal; } - get self(): Ray { return this.vertex; }; set self(self: Arbitrary) { this.vertex = self; } + get self(): Ray { return this.vertex; }; set self(self: JS.Arbitrary) { this.vertex = self; } - constructor({ initial, vertex, terminal, }: Partial> = {}) { + constructor({ initial, vertex, terminal, }: { + initial?: JS.Arbitrary, + vertex?: JS.Arbitrary, + terminal?: JS.Arbitrary, + } = {}) { this._initial = initial ?? Ray.None; this._vertex = vertex ?? this.self_reference; // TODO: None, could also self-reference the ray on which it's defining to be None. Now it's just an ignorant loop. this._terminal = terminal ?? Ray.None; @@ -243,7 +241,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } /** [ ] */ static None = () => new Ray({ }).o({ }); - /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { + /** [--?--] */ static vertex = (value: JS.Arbitrary = Ray.None) => { /** [ ] */ const vertex = Ray.None(); /** [-- ] */ vertex.initial = vertex.___empty_initial(); /** [ ? ] */ vertex.vertex = value; @@ -262,7 +260,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); // TODO: Difference between () => this & this.as_arbitrary , relevant for lazy/modular/ignorant structures etc.. - as_arbitrary = (): Arbitrary => () => this; + as_arbitrary = (): JS.Arbitrary => () => this; /** * TODO : COMPOSE EMPTY AS FIRST ELEMENT: @@ -296,8 +294,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * @see "Continuations as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence */ - static compose = Ray.___func(ref => { - let { initial, terminal} = ref.self; + static compose = JS.Function.Impl((initial, terminal) => { if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) throw new PreventsImplementationBug(); @@ -325,8 +322,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies */ - static equivalent = Ray.___func(ref => { - let { initial, terminal} = ref.self; + static equivalent = JS.Function.Impl((initial, terminal) => { /** * The simplest case, is where both sides are only aware of themselves (on .vertex). The only thing we need to do is turn an Orbit, to an Orbit which repeats every 2 steps, the intermediate step being the other thing. @@ -476,8 +472,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... // [[a,d,g],[b,e,h],[c,f,i]] - static zip = Ray.___func(ref => { - let { initial, terminal } = ref.self; + static zip = JS.Function.Impl((initial, terminal) => { if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) throw new PreventsImplementationBug('TODO: Implement'); @@ -516,75 +511,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } }); - - // static sn = (step: Implementation): { - // as_method: ArbitraryMethod - // } => { - // - // return { - // as_method: Ray.___func(step).as_method - // } - // } - - /** - * Constructs a function accepting arbitrary structure based on one implementation of it. - * - * TODO: Is there some equivalent of this in computer science??? category theory?? - * - * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = [[a1, [[[a2]]], [[[[]]], []]], b, [[[]], [], [c]]].compose = ... - */ - static ___func( - step: Implementation, - ): { - as_method: ArbitraryMethod - } { - return { - - /** - * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] - */ - as_method: (ref: Ray): Method => (...any: Recursive): Ray => { - if (any === undefined || any.length === 0) - return step(ref); - - // TODO: This can be much better... - const first = (recursive?: Recursive): Ray | undefined => { - if (recursive === undefined) return; - // if (_.isObject(recursive)) return recursive as unknown as Ray; - - for (let r of recursive) { - if (r === undefined) continue; - if (_.isObject(r)) return r as unknown as Ray; - - // if (r instanceof Ray) - // throw new PreventsImplementationBug(); - - // @ts-ignore - const _first = first(r); - if (_first) - return _first; - } - } - - const _first = first(any); - - if (_first === undefined) - return step(ref); - - const pointer = new Ray({ - initial: () => ref, - terminal: () => _first - }); - - return step(pointer); - - // TODO: ANY CASE - // if (any.length === 1) { - // } - } - } - } - /** * Helper methods for commonly used directions * @@ -597,7 +523,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } // TODO: Nicer one? ; Differentiate between ".next" and just "follow the pointer" ? - follow = (step: Implementation = Ray.directions.next): Ray => { + follow = (step: JS.Implementation = Ray.directions.next): Ray => { // let pointer = new Ray({ // initial: () => this, // terminal: () => step(this), @@ -613,7 +539,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? /** * .next */ - next = (step: Implementation = Ray.directions.next): Ray => { + next = (step: JS.Implementation = Ray.directions.next): Ray => { return [...this.traverse(step)][1] ?? Ray.None(); // TODO BAD // for (let next of this.traverse(step)) { // @@ -641,19 +567,19 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // return Ray.___next(Ray.directions.next)(this); } - has_next = (step: Implementation = Ray.directions.next): boolean => this.next(step).is_some(); + has_next = (step: JS.Implementation = Ray.directions.next): boolean => this.next(step).is_some(); // @alias('end', 'result', 'back') - last = (step: Implementation = Ray.directions.next): Ray => { + last = (step: JS.Implementation = Ray.directions.next): Ray => { const next = this.next(step); return next.is_some() ? next.last(step) : this; } /** * .previous (Just .next with a `Ray.directions.previous` default) */ - previous = (step: Implementation = Ray.directions.previous): Ray => this.next(step); - has_previous = (step: Implementation = Ray.directions.previous): boolean => this.has_next(step); + previous = (step: JS.Implementation = Ray.directions.previous): Ray => this.next(step); + has_previous = (step: JS.Implementation = Ray.directions.previous): boolean => this.has_next(step); // @alias('beginning', 'front') - first = (step: Implementation = Ray.directions.previous): Ray => this.last(step); + first = (step: JS.Implementation = Ray.directions.previous): Ray => this.last(step); // TODO: I Don't like this name, but it needs to get across that any equivalency, or any equivalency check for that necessarily, is local. And I want more equivalences, I run more of this method. // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. @@ -755,7 +681,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? permutation === undefined ? 1 : of ) - at = (steps: number | Ray | Arbitrary): Ray => { + at = (steps: number | Ray | JS.Arbitrary): Ray => { if (!JS.is_number(steps)) throw new NotImplementedError('Not yet implemented for Rays.'); @@ -814,7 +740,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // ___compute = () - *traverse(step: Implementation = Ray.directions.next): Generator { + *traverse(step: JS.Implementation = Ray.directions.next): Generator { // TODO: Also to ___func?? if (this.type !== RayType.VERTEX) @@ -823,11 +749,11 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? yield *this.___next({step}); } - static pointer = (initial: Ray, step: Implementation): Ray => new Ray({ + static pointer = (initial: Ray, step: JS.Implementation): Ray => new Ray({ initial: () => initial, terminal: () => step(initial) }); - private next_pointer = (step: Implementation) => { + private next_pointer = (step: JS.Implementation) => { const { self: history, terminal: current } = this; return new Ray({ @@ -1000,8 +926,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * * TODO: switch/match Should be abstracted into Ray? */ - static step = (ref: Ray) => { - const { initial } = ref; + static step = JS.Function.Impl((initial, terminal) => { + // TODO: Can be ignorant of terminal is initial is a reference. (probably some performance thing) /** * Should return vertex, for one possible next step @@ -1024,9 +950,9 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * - TODO: Could return both dereference sides as possible options */ - const next_pointer = (terminal: Ray, next: Arbitrary) => new Ray({ + const next_pointer = (terminal: Ray, next: JS.Arbitrary) => new Ray({ initial: () => terminal, - vertex: () => ref, + // vertex: () => ref,? TODO HISTORY terminal: next, }); @@ -1088,15 +1014,15 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * VERTEX -> REFERENCE * TODO ??? */ - [RayType.VERTEX]: (initial) => dereference(ref.terminal), + [RayType.VERTEX]: (initial) => dereference(terminal), - [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL)(ref.terminal), - [RayType.TERMINAL]: (initial) => boundary(RayType.TERMINAL)(ref.terminal), + [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL)(terminal), + [RayType.TERMINAL]: (initial) => boundary(RayType.TERMINAL)(terminal), [RayType.REFERENCE]: dereference, }); - } - step= Ray.___func(Ray.step).as_method(this); + }); + step = Ray.step.as_method(this); // TODO; Maybe replace switch with 'zip'?, What are the practical differences? ___primitive_switch = (cases: SwitchCases TResult)>): TResult => { @@ -1137,7 +1063,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * TODO: * - This needs something much smarter at some point... */ - all = (step: Implementation = Ray.directions.next): { [key: string | symbol]: Ray } & any => { + all = (step: JS.Implementation = Ray.directions.next): { [key: string | symbol]: Ray } & any => { return new Proxy(this, { get(self: Ray, p: string | symbol, receiver: any): any { @@ -1198,7 +1124,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? protected _proxy: any; protected _dirty_store: { [key: string | symbol]: object } = {} - protected proxy = (constructor?: ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: + protected proxy = (constructor?: JS.ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: // TODO: IMPLEMENT SPLAT... {...ray.any} return this._proxy ??= new Proxy(this, { @@ -1530,125 +1456,3 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? // }) // - -/** - * - * Important to remember this is just one particular structure to which it can be mapped, there are probably many (TODO infinitely?) others. - * - * Not to be considered as a perfect mapping of JavaScript functionality - merely a practical one. - */ -export namespace JS { - export const Boolean = (boolean: boolean): Ray => { - // TODO: Could be superpose structure instead of length 2; - // |-false->-true-| (could of course also be reversed) - const _false = Ray.vertex().o({ js: false }).as_reference(); - const _true = Ray.vertex().o({ js: true }).as_reference(); - _false.compose(_true); - - return (boolean ? _true : _false); - } - // export const bit = (bit?: boolean): Arbitrary> => permutation(bit ? 1 : 0, 2); - export const Bit = Boolean; - - export const Iterable = (iterable: Iterable): Ray => JS.Iterator(iterable[Symbol.iterator]()); - - export const Iterator = (iterator: Iterator): Ray => { - // [ |--] - - const next = (previous: Ray, first: boolean = false): Ray => { - const iterator_result = iterator.next(); - const is_terminal = iterator_result.done === true; - - // Clear the terminal function attached to the Iterator. - // TODO: In case of 'is_terminal = true': Could also leave this be, in case JavaScript allows for adding stuff to the iterator even after .done === true; - previous.self.terminal = previous.self.___empty_terminal(); - - if (is_terminal) { - // We're done, this is the end of the iterator - - return Ray.None(); - } - - const current = Ray - .vertex(() => JS.Any(iterator_result.value)) - .o({js: iterator_result.value}) - .as_reference(); - - // Move the iterator to the terminal. - current.self.terminal = () => next(current); - - if (first) { - // Move the iterator's terminal to current. - ray_iterator.self.terminal = () => current.self; - - current.self.initial = () => ray_iterator.self; - - return current; // Answer to INITIAL.terminal is a VERTEX. - } - - // TODO: This is just compose, but without .type checks.. ; FIX ON COMPOSE END for is_reference etc.. - if (previous.follow().type !== RayType.TERMINAL) - throw new PreventsImplementationBug(); - if (current.follow(Ray.directions.previous).type !== RayType.INITIAL) - throw new PreventsImplementationBug(); - - previous.follow().equivalent(current.follow(Ray.directions.previous)); - // TODO: - // previous.compose(current); - - return current.self.initial; // Answer to VERTEX.terminal is an INITIAL. - } - - const ray_iterator: Ray = new Ray({ - vertex: Ray.None, - terminal: () => next(ray_iterator, true), - }) - .o({ js: iterator }) - .as_reference(); - - return ray_iterator; - } - - export const Generator = (generator: Generator): Ray => JS.Iterable(generator); - - // TODO Could have parallel threads in general. - // export const AsyncGenerator = (generator: AsyncGenerator): Ray => { - // // [ |--] - // return JS.Iterable(generator); - // } - - export const Number = (number: number): Ray => { - throw new NotImplementedError(); - } - - export const Function = (func: Arbitrary): Ray => { - throw new NotImplementedError(); - } - - // TODO - export const Object = (object: object): Ray => Ray.vertex().o(object).as_reference(); - - export const Any = (any: any): Ray => { - if (any === null || any === undefined) return JS.Any(any); - if (JS.is_boolean(any)) return JS.Boolean(any); - if (JS.is_number(any)) return JS.Number(any); - if (JS.is_iterable(any)) return JS.Iterable(any); // || is_array(any)) - if (JS.is_function(any)) return JS.Function(any); - if (JS.is_object(any)) return JS.Object(any); - - // TODO - // return JS.Any(any); - return Ray.vertex().o({js: any}).as_reference(); - } - - export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); - export const is_number = (_object: any): _object is number => _.isNumber(_object); - export const is_object = (_object: any): _object is object => _.isObject(_object); - export const is_iterable = (_object: any): _object is Iterable => Symbol.iterator in Object(_object) && is_function(_object[Symbol.iterator]); - export const is_async_iterable = (_object: any): _object is AsyncIterable => Symbol.asyncIterator in Object(_object); - export const is_array = (_object: any): _object is T[] => _.isArray(_object); - export const is_async = (_object: any) => _.has(_object, 'then') && is_function(_.get(_object, 'then')); // TODO, Just an ugly check - - export const is_error = (_object: any): _object is Error => _.isError(_object); - export const is_function = (_object: any): _object is ((...args: any[]) => any) => _.isFunction(_object); -} \ No newline at end of file From 356588da0788c411d3be7bf0a30548d30d8dc1ef Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Sun, 21 Jan 2024 19:34:01 +0100 Subject: [PATCH 108/138] 2024/01/21 - Moving function implementation to JS.ts --- .../debug/QuickVisualizationInterface.tsx | 5 +-- src/@orbitmines/external/chyp/Chyp.ts | 31 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx b/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx index 6b11cd0..c846585 100644 --- a/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx +++ b/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx @@ -13,11 +13,12 @@ import { torus } from "../OrbitMinesExplorer"; import {HotkeyEventOptions, useHotkeys} from "../../js/react/hooks/useHotkeys"; -import {Implementation, Ray, RayType} from "../Ray"; +import {Ray, RayType} from "../Ray"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import _ from "lodash"; import {useThree} from "@react-three/fiber"; import {StatsPanels} from "./DebugCanvas"; +import JS from "../JS"; const ___index = (ray: Ray): number => { switch (ray.type) { @@ -349,7 +350,7 @@ export const QuickVisualizationInterface = ({scale = 1.5}: InterfaceOptions) => // TODO Then expand these to any-dimensional ]; const isFollowing = directions.map( - ([initial, terminal]): Implementation => { + ([initial, terminal]): JS.Implementation => { const toInitial = initial.some(option => pressed.includes(option)); const toTerminal = terminal.some(option => pressed.includes(option)); diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index 3ee736d..6dd6da2 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -1,5 +1,6 @@ -import {Arbitrary, Ray} from "../../explorer/Ray"; +import {Ray} from "../../explorer/Ray"; import {NotImplementedError} from "../../explorer/errors/errors"; +import JS from "../../explorer/JS"; /** * An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Rays. @@ -32,22 +33,22 @@ export namespace Chyp { } // Vertex.in_edges = Ray.initial - get in_edges(): Ray { return this.initial; } set in_edges(ray: Arbitrary) { this.initial = ray; } + get in_edges(): Ray { return this.initial; } set in_edges(ray: JS.Arbitrary) { this.initial = ray; } // Vertex.out_edges = Ray.terminal - get out_edges(): Ray { return this.terminal; } set out_edges(ray: Arbitrary) { this.terminal = ray; } + get out_edges(): Ray { return this.terminal; } set out_edges(ray: JS.Arbitrary) { this.terminal = ray; } } export type EData = Edge; export class Edge extends Ray { // Edge.source = Ray.initial - get source(): Ray { return this.initial; } set source(ray: Arbitrary) { this.initial = ray; } - get s(): Ray { return this.initial; } set s(ray: Arbitrary) { this.initial = ray; } + get source(): Ray { return this.initial; } set source(ray: JS.Arbitrary) { this.initial = ray; } + get s(): Ray { return this.initial; } set s(ray: JS.Arbitrary) { this.initial = ray; } // Edge.targets = Ray.terminal - get target(): Ray { return this.terminal; } set target(ray: Arbitrary) { this.terminal = ray; } - get t(): Ray { return this.terminal; } set t(ray: Arbitrary) { this.terminal = ray; } + get target(): Ray { return this.terminal; } set target(ray: JS.Arbitrary) { this.terminal = ray; } + get t(): Ray { return this.terminal; } set t(ray: JS.Arbitrary) { this.terminal = ray; } } @@ -73,10 +74,10 @@ export namespace Chyp { } // Match.domain = Ray.initial - get domain(): Ray { return this.initial; } set domain(ray: Arbitrary) { this.initial = ray; } + get domain(): Ray { return this.initial; } set domain(ray: JS.Arbitrary) { this.initial = ray; } // Match.codomain = Ray.terminal - get codomain(): Ray { return this.terminal; } set codomain(ray: Arbitrary) { this.terminal = ray; } + get codomain(): Ray { return this.terminal; } set codomain(ray: JS.Arbitrary) { this.terminal = ray; } } @@ -91,10 +92,10 @@ export namespace Chyp { } // Rule.lhs = Ray.initial - get lhs(): Ray { return this.initial; } set lhs(ray: Arbitrary) { this.initial = ray; } + get lhs(): Ray { return this.initial; } set lhs(ray: JS.Arbitrary) { this.initial = ray; } // Rule.rhs = Ray.terminal - get rhs(): Ray { return this.terminal; } set rhs(ray: Arbitrary) { this.terminal = ray; } + get rhs(): Ray { return this.terminal; } set rhs(ray: JS.Arbitrary) { this.terminal = ray; } /** * TODO: We can use the same implementation to rewrite where there's not necessarily a match between initial/terminal side of a rule. @@ -141,12 +142,12 @@ export namespace Chyp { } // Graph.inputs = Ray.initial - get inputs(): Ray { return this.initial; } set inputs(ray: Arbitrary) { this.initial = ray; } - set_inputs = (ray: Arbitrary): Graph => { this.inputs = ray; return this; } + get inputs(): Ray { return this.initial; } set inputs(ray: JS.Arbitrary) { this.initial = ray; } + set_inputs = (ray: JS.Arbitrary): Graph => { this.inputs = ray; return this; } add_inputs = (ray: Ray): Graph => { this.inputs.compose(ray); return this; } // Graph.inputs = Ray.terminal - get outputs(): Ray { return this.terminal; } set outputs(ray: Arbitrary) { this.terminal = ray; } - set_outputs = (ray: Arbitrary): Graph => { this.outputs = ray; return this; } + get outputs(): Ray { return this.terminal; } set outputs(ray: JS.Arbitrary) { this.terminal = ray; } + set_outputs = (ray: JS.Arbitrary): Graph => { this.outputs = ray; return this; } add_outputs = (ray: Ray): Graph => { this.outputs.compose(ray); return this; } } From 8184893cbaeeaa4cb115f7abe197f590c78af9aa Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 22 Jan 2024 00:40:59 +0100 Subject: [PATCH 109/138] 2024/01/21 - WIP Refactor of all traversal/stepping funcs --- src/@orbitmines/explorer/JS.ts | 30 +++++- src/@orbitmines/explorer/Ray.ts | 162 +++++++++++++++++++++++++------- 2 files changed, 153 insertions(+), 39 deletions(-) diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts index 0528879..6b28a98 100644 --- a/src/@orbitmines/explorer/JS.ts +++ b/src/@orbitmines/explorer/JS.ts @@ -40,15 +40,35 @@ namespace JS { * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] */ static Ref = = Ray>(impl: (ref: T) => T): Function => { - return new Function(impl); + return new Function(impl); // TODO: THIS SHOULD CHANGE, TO ON VERTEX. } - static Impl = = Ray>(impl: (initial: T, terminal: T) => T): Function => { return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); } - static IgnorantOfInitial = = Ray>(impl: (terminal: T) => T): Function => Function.Impl((_, terminal) => impl(terminal)); - static IgnorantOfTerminal = = Ray>(impl: (initial: T) => T): Function => Function.Impl((initial, _) => impl(initial)); - static Ignorant = = Ray>(impl: ParameterlessFunction): Function => Function.Impl(impl); + // static IgnorantOfInitial = = Ray>(impl: (terminal: T) => T): Function => Function.Impl((_, terminal) => impl(terminal)); + // static IgnorantOfTerminal = = Ray>(impl: (initial: T) => T): Function => Function.Impl((initial, _) => impl(initial)); + // static Ignorant = = Ray>(impl: ParameterlessFunction): Function => Function.Impl(impl); + + /** + * TODO: Reversible through memory... + */ + static WithMemory = = Ray>(impl: (initial: T, terminal: T) => T): Function => { + // return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); + throw new NotImplementedError(); + } + + /** + * @see "Reversibility after ignoring some difference": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Another%20example%20of%20this%20is%20reversibility + */ + static Reversible = = Ray>( + // @alias('backward') + initial: (ref: T) => T, + // @alias('forward') + terminal: (ref: T) => T, + ): Function => { + // return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); + throw new NotImplementedError(); + } /** * Constructs a class method accepting arbitrary structure. diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 950ef08..c9b4beb 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -3,6 +3,7 @@ import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; import JS from "./JS"; + // TODO: SHOULDNT CLASSIFY THESE? (And incorporate in Ray??) export enum RayType { // NONE = ' ', @@ -148,7 +149,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. */ static is_orbit = (a: Ray, b: Ray) => a === b; // is, ..., appears equal. - protected self_reference = () => this; + protected get self_reference() { return this.as_arbitrary(); }; is_some = (): boolean => !this.is_none(); @@ -521,6 +522,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? previous: (ref: Ray) => ref.self.initial.as_reference(), none: (ref: Ray) => ref, // Note that "None" is necessarily inconsistent } + static follow_direction = { + [RayType.INITIAL]: Ray.directions.next, + [RayType.TERMINAL]: Ray.directions.previous + } // TODO: Nicer one? ; Differentiate between ".next" and just "follow the pointer" ? follow = (step: JS.Implementation = Ray.directions.next): Ray => { @@ -531,41 +536,13 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? return step(this); } - follow_direction = (): Ray => this.___primitive_switch({ - [RayType.INITIAL]: Ray.directions.next, - [RayType.TERMINAL]: Ray.directions.previous, - }); + follow_direction = (): Ray => this.___primitive_switch({...Ray.follow_direction}); /** * .next */ next = (step: JS.Implementation = Ray.directions.next): Ray => { return [...this.traverse(step)][1] ?? Ray.None(); // TODO BAD - // for (let next of this.traverse(step)) { - // - // return next; - // } - // - // return Ray.None(); - // for (let next of this.___next({step})) { - // - // // return next; - // } - // - // return Ray.None(); - // let pointer = new Ray({ - // initial: () => this, - // terminal: () => step(this), - // }); - // - // pointer = pointer.step().step(); - // - // if (pointer.terminal.type !== RayType.VERTEX) - // throw new NotImplementedError(`${pointer.terminal.type} / ${pointer.terminal.self.any.js}`); - // - // return pointer.terminal; - - // return Ray.___next(Ray.directions.next)(this); } has_next = (step: JS.Implementation = Ray.directions.next): boolean => this.next(step).is_some(); // @alias('end', 'result', 'back') @@ -786,6 +763,126 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } } + static *traverse(options = { + initial: Ray.None(), + step: Ray.directions.next, + branch: { + // @alias('pruning', 'mapping', 'filtering') + prune: (branches: Ray): Ray => branches, + // @alias('next', 'selection', 'tactic', 'strategy') + next: (branches: Ray): Ray => branches.first(), + } + }): Generator<{ + branch: Ray, + vertex: Ray, + }> { + /** + * An arbitrary Ray of (accessible) (possible) next steps to perform in traversal. + */ + // @alias('cursor(s)', 'branch(es)', 'selection(s)') + let branches: Ray = Ray.None(); + + while (true) { + /** + * Branch *Pruning, Mapping, ..., Filtering* + */ + branches = options.branch.prune(branches); // TODO: Could hold history + + /** + * Branch *Selection, Tactic, ..., Strategy* + */ + + /** + * An arbitrary Ray of (requested) next steps to perform in parallel/.../superposition (with respect to all the other branches). + */ + const branches_to_traverse: Ray = options.branch.next(branches); + + /** + * Make copies of our traversal for each selected branch + */ + // TODO + + /** + * Split off traversal to each branch, selecting their respective . + */ + + let branch: Ray = branches_to_traverse; //TODO + + const initial = branch.previous(); + const terminal = branch; + + const step = () => { + const traverse_boundary = (): Ray => { + return branch.___primitive_switch({ + [RayType.REFERENCE]: (self) => self.dereference, + + /** + * A possible continuation + * INITIAL/TERMINAL -> possible previous - TERMINAL.self.initial (pass to step) + * TERMINAL/INITIAL -> possible next - INITIAL.self.terminal (pass to step) + */ + [RayType.INITIAL]: Ray.follow_direction[RayType.INITIAL], + [RayType.TERMINAL]: Ray.follow_direction[RayType.TERMINAL], + + /** + * This is the most interesting case: Many possible continuations (from the perspective of a boundary (INITIAL/TERMINAL)). + * + * NOTE: + * - There are many ways of actually implementing this. This is one which ensures the checks needed to traverse arbitrary continuations is always local (with the trade-off that you can't disambiguate between structure on edges vs structure on vertices by default). Though this can be imposed with something else. (TODO) + * + * @see = TODO + */ + [RayType.VERTEX]: (terminal) => { + const initial = branch.previous(); + // TODO: Could check if self.self is Orbit. + + /** + * Simplest check, ensure we're coming from some place which splits into many branches + * @see = TODO + */ + if (Ray.is_orbit(initial.self, terminal.self.self)) { + // TODO: Branch to previous.next + throw new NotImplementedError(); + } + + /** + * This is the one which disallows structure on edges, and assumes a vertex it finds, necessarily as additional vertices we're looking for. (But we don't need to keep track of where we are like this) + * @see = TODO + */ + if ( + terminal.dereference.is_boundary() // Whether there's a continuation defined on the vertex. + && Ray.is_orbit(terminal.self, terminal.self.self.self) + ) { + // TODO: Split of options.step(terminal) & new Ray({ + // initial: terminal.as_arbitrary(), + // vertex: pointer.as_arbitrary(), + // terminal: () => terminal.dereference + // }) + throw new NotImplementedError(); + } + + return options.step(terminal); + } + }); + } + + return initial.___primitive_switch({ + [RayType.VERTEX]: (self) => options.step(self), // TODO dereference + [RayType.INITIAL]: (self) => traverse_boundary(), + [RayType.TERMINAL]: (self) => traverse_boundary(), + [RayType.REFERENCE]: (self) => self.dereference, + }); + } + + // After step, if IS_TERMINAL, nothing. assume halting (!!!at prune step ?) + + const terminal = branch.follow(); + + // branch.self = terminal; + + } + } + /** * TODO: Not happy with this... */ @@ -956,10 +1053,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? terminal: next, }); - /** - * INITIAL/TERMINAL -> possible previous - TERMINAL.self.initial (pass to step) - * TERMINAL/INITIAL -> possible next - INITIAL.self.terminal (pass to step) - */ + const follow_direction = (terminal: Ray): Ray => next_pointer(terminal, () => terminal.follow_direction()); const dereference = (terminal: Ray) => next_pointer(terminal, () => terminal.dereference); From 66c4611f4aa4a468b574451f526b269b33c0ff70 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 22 Jan 2024 00:48:26 +0100 Subject: [PATCH 110/138] 2024/01/21 - WIP Refactor of all traversal/stepping funcs --- src/@orbitmines/explorer/Ray.ts | 73 ++++----------------------------- 1 file changed, 9 insertions(+), 64 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index c9b4beb..5b6d53d 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -808,12 +808,18 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? let branch: Ray = branches_to_traverse; //TODO - const initial = branch.previous(); + const initial = branch.previous(); // TODO hold history ; discard more than one step for this implementation, optionally switch const terminal = branch; const step = () => { const traverse_boundary = (): Ray => { return branch.___primitive_switch({ + /** + * Dereferencing is likely in many cases quickly subject to infinite stepping (similar to INITIAL -> INITIAL, TERMINAL -> TERMINAL, VERTEX -> VERTEX. (Could be that this means that there's no continuation, a self-reference defined here, or it's some mechanism of halting.) + * + * - TODO: Simple example of infinitely finding terminals, or a reference to 'nothing - infinitely'. + * - TODO: If both are references, allow deref of both? + */ [RayType.REFERENCE]: (self) => self.dereference, /** @@ -846,7 +852,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? } /** - * This is the one which disallows structure on edges, and assumes a vertex it finds, necessarily as additional vertices we're looking for. (But we don't need to keep track of where we are like this) + * This is the one which disallows structure on edges, and assumes a vertex it finds, necessarily as additional vertices we're looking for. (But we don't need to keep track of where we are like this ; TODO: Implement variant which checks back over branch.previous() to allow for this) * @see = TODO */ if ( @@ -1018,38 +1024,10 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? throw new PreventsImplementationBug(`${pointers.length} left`) } - /** - * - * - * TODO: switch/match Should be abstracted into Ray? - */ static step = JS.Function.Impl((initial, terminal) => { - // TODO: Can be ignorant of terminal is initial is a reference. (probably some performance thing) - - /** - * Should return vertex, for one possible next step - * Initial for many - * Terminal for none - * Reference for ??? - */ - - /** - * Dereferencing is likely in many cases quickly subject to infinite stepping. - * - * REFERENCE -> Dereference (this.self.self) - * INITIAL/INITIAL -> Dereference (this.self.terminal) - * TERMINAL/TERMINAL -> Dereference (this.self.initial) - * VERTEX/VERTEX -> ??? - * - * - Could be that this means that there's no continuation, a self-reference defined here, or it's some mechanism of halting. - * - * - TODO: Simple example of infinitely finding terminals, or a reference to 'nothing - infinitely'. - * - TODO: Could return both dereference sides as possible options - */ const next_pointer = (terminal: Ray, next: JS.Arbitrary) => new Ray({ initial: () => terminal, - // vertex: () => ref,? TODO HISTORY terminal: next, }); @@ -1058,10 +1036,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? const dereference = (terminal: Ray) => next_pointer(terminal, () => terminal.dereference); - /** - * TERMINAL -> VERTEX (next: VERTEX -> INITIAL) - * INITIAL -> VERTEX (next: VERTEX -> TERMINAL) - */ const arbitrary_continuations = (terminal: Ray): Ray => next_pointer(terminal, () => initial.___primitive_switch({ [RayType.INITIAL]: (initial) => Ray.directions.next(terminal), [RayType.TERMINAL]: (initial) => Ray.directions.previous(terminal), @@ -1069,22 +1043,8 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? const boundary = (boundary: Boundary) => (terminal: Ray): Ray => terminal.___primitive_switch({ - /** - * Many possible continuations (from the perspective of initial = TERMINAL) - * - * From something, we arrived at some TERMINAL/INITIAL, which at its `.self`, holds a VERTEX. - * [ ? ] - * [--|--][--| ] <-- ref superposed with ref.self - * [ ? ] - */ [RayType.VERTEX]: arbitrary_continuations, - /** - * A possible continuation - * - * (INITIAL -> TERMINAL) - * (TERMINAL -> INITIAL) - */ [boundary]: follow_direction, [opposite(boundary)]: follow_direction, @@ -1092,22 +1052,6 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? }); return initial.___primitive_switch({ - - /** - * VERTEX -> VERTEX - * TODO Could be an ignorant continuation (as in, the terminal does not have the initial vertex on its .initial). Or you could interpret this as saying, oh this should be a vertex, no information about the continuation definition in between? - * - * VERTEX -> TERMINAL - * If we're going in the terminal direction (from the perspective of the initial = VERTEX) - * [--|--][--| ] <-- (VERTEX -> TERMINAL) - * - * VERTEX -> INITIAL - * If we're going in the initial direction (from the perspective of the initial = VERTEX) - * [ |--][--|--] <-- (VERTEX -> INITIAL) - * - * VERTEX -> REFERENCE - * TODO ??? - */ [RayType.VERTEX]: (initial) => dereference(terminal), [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL)(terminal), @@ -1119,6 +1063,7 @@ export class Ray // Other possibly names: AbstractDirectionality, ..., ?? step = Ray.step.as_method(this); // TODO; Maybe replace switch with 'zip'?, What are the practical differences? + // TODO: switch/match Should be abstracted into Ray? ___primitive_switch = (cases: SwitchCases TResult)>): TResult => { const _case = cases[this.type]; From 5973568e3cda9ab87d3361170941524b33155029 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 22 Jan 2024 23:15:40 +0100 Subject: [PATCH 111/138] 2024/01/22 - Refactoring Ray.ts & JS.ts into something acceptable --- src/@orbitmines/explorer/JS.spec.ts | 457 ++- src/@orbitmines/explorer/JS.ts | 250 +- src/@orbitmines/explorer/JS2.ts | 252 ++ src/@orbitmines/explorer/Ray.spec.ts | 3472 +++++++++-------- src/@orbitmines/explorer/Ray.ts | 1566 +------- src/@orbitmines/explorer/Ray2.ts | 1059 +++++ src/@orbitmines/explorer/Ray3.ts | 181 + .../debug/QuickVisualizationInterface.tsx | 2 +- src/@orbitmines/external/chyp/Chyp.ts | 28 +- src/@orbitmines/rays/index.ts | 2 + 10 files changed, 3692 insertions(+), 3577 deletions(-) create mode 100644 src/@orbitmines/explorer/JS2.ts create mode 100644 src/@orbitmines/explorer/Ray2.ts create mode 100644 src/@orbitmines/explorer/Ray3.ts create mode 100644 src/@orbitmines/rays/index.ts diff --git a/src/@orbitmines/explorer/JS.spec.ts b/src/@orbitmines/explorer/JS.spec.ts index 95d567b..8a61e76 100644 --- a/src/@orbitmines/explorer/JS.spec.ts +++ b/src/@orbitmines/explorer/JS.spec.ts @@ -1,214 +1,255 @@ -import {Ray, RayType} from "./Ray"; +import Ray from "./Ray"; import JS from "./JS"; +import {previous} from "slate"; +import {NotImplementedError} from "./errors/errors"; describe("JS", () => { - test(".Function.Ref(ref)", () => { - const method = JS.Function.Ref((ref): Ray => new Ray({ - initial: ref.self.initial.as_arbitrary(), - terminal: ref.self.terminal.as_arbitrary() - }).o({ js: ref.type })).as_method; - expect(method(Ray.vertex().as_reference().as_reference())().any.js).toBe(RayType.REFERENCE); - expect(method(Ray.vertex().as_reference())().any.js).toBe(RayType.VERTEX); - expect(method(Ray.initial().as_reference())().any.js).toBe(RayType.INITIAL); - expect(method(Ray.terminal().as_reference())().any.js).toBe(RayType.TERMINAL); - const a = Ray.vertex().o({ js: 'A'}).as_reference(); - const b = Ray.vertex().o({ js: 'B'}).as_reference(); - - // TODO What about method(a)(b)(c)... :thinking: - expect(method(a)(b).initial.any.js).toBe('A'); - expect(method(a)(b).terminal.any.js).toBe('B'); - expect(method(a)(b).type).toBe(RayType.VERTEX); - }); - test(".Object", () => { - const ray = JS.Object({ - a: 'b', - position: [0, 1, 2], - func: () => 'c' - }); - - expect(ray.any.a).toBe('b'); - expect(ray.any.undefinedProperty).toBe(undefined); - expect(() => ray.any.undefinedFunction()).toThrow(); - expect(ray.any.position).toEqual([0, 1, 2]); - expect(ray.any.func()).toBe('c'); - }); - test(".Boolean", () => { - const _false = JS.Boolean(false); - const _true = JS.Boolean(true); - - expect(_false.any.js).toBe(false); - expect(_true.any.js).toBe(true); - - expect(_false.next().any.js).toBe(true); - expect(_false.previous().is_none()).toBe(true); - - expect(_true.next().is_none()).toBe(true); - expect(_true.previous().any.js).toBe(false); - }); - test(".Bit", () => { - const _false = JS.Bit(false); - const _true = JS.Bit(true); - - expect(_false.any.js).toBe(false); - expect(_true.any.js).toBe(true); - - expect(_false.next().any.js).toBe(true); - expect(_false.previous().is_none()).toBe(true); - - expect(_true.next().is_none()).toBe(true); - expect(_true.previous().any.js).toBe(false); - }); - test(".Iterable", () => { - const iterable = JS.Iterable(['A', 'B', 'C', 'D', 'E']); - - expect(iterable.type).toBe(RayType.INITIAL); - - const A = iterable.follow(); - - expect(A.any.js).toBe('A'); - expect(A.previous().is_none()).toBe(true); - - expect(A.next().previous().any.js).toBe('A'); - expect(A.next().next().previous().previous().any.js).toBe('A'); - expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); - expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); - - expect(A.next().any.js).toBe('B'); - expect(A.next().next().any.js).toBe('C'); - expect(A.next().next().next().any.js).toBe('D'); - expect(A.next().next().next().next().any.js).toBe('E'); - - expect(A.next().next().next().next().next().is_none()).toBe(true); - - expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); - expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); - expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); - }); - test(".Generator", () => { - function* generator_function(): Generator { - yield 'A'; - yield 'B'; - yield 'C'; - yield 'D'; - yield 'E'; - } - const generator = JS.Generator(generator_function()); - - expect(generator.type).toBe(RayType.INITIAL); - - const A = generator.follow(); - - expect(A.any.js).toBe('A'); - expect(A.previous().is_none()).toBe(true); - - expect(A.next().previous().any.js).toBe('A'); - expect(A.next().next().previous().previous().any.js).toBe('A'); - expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); - expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); - - expect(A.next().any.js).toBe('B'); - expect(A.next().next().any.js).toBe('C'); - expect(A.next().next().next().any.js).toBe('D'); - expect(A.next().next().next().next().any.js).toBe('E'); - - expect(A.next().next().next().next().next().is_none()).toBe(true); - - expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); - expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); - expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); - }); - test(".Any", () => { - - // .Object - { - const ray = JS.Any({ - a: 'b', - position: [0, 1, 2], - func: () => 'c' - }); - - expect(ray.any.a).toBe('b'); - expect(ray.any.undefinedProperty).toBe(undefined); - expect(() => ray.any.undefinedFunction()).toThrow(); - expect(ray.any.position).toEqual([0, 1, 2]); - expect(ray.any.func()).toBe('c'); - } - // .Boolean - { - const _false = JS.Any(false); - const _true = JS.Any(true); - - expect(_false.any.js).toBe(false); - expect(_true.any.js).toBe(true); - - expect(_false.next().any.js).toBe(true); - expect(_false.previous().is_none()).toBe(true); - - expect(_true.next().is_none()).toBe(true); - expect(_true.previous().any.js).toBe(false); - } - // .Iterable - { - const iterable = JS.Any(['A', 'B', 'C', 'D', 'E']); - - expect(iterable.type).toBe(RayType.INITIAL); - - const A = iterable.follow(); - - expect(A.any.js).toBe('A'); - expect(A.previous().is_none()).toBe(true); - - expect(A.next().previous().any.js).toBe('A'); - expect(A.next().next().previous().previous().any.js).toBe('A'); - expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); - expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); - - expect(A.next().any.js).toBe('B'); - expect(A.next().next().any.js).toBe('C'); - expect(A.next().next().next().any.js).toBe('D'); - expect(A.next().next().next().next().any.js).toBe('E'); - - expect(A.next().next().next().next().next().is_none()).toBe(true); - - expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); - expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); - expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); - } - // .Generator - { - function* generator_function(): Generator { - yield 'A'; - yield 'B'; - yield 'C'; - yield 'D'; - yield 'E'; - } - const generator = JS.Any(generator_function()); - - expect(generator.type).toBe(RayType.INITIAL); - - const A = generator.follow(); - - expect(A.any.js).toBe('A'); - expect(A.previous().is_none()).toBe(true); - - expect(A.next().previous().any.js).toBe('A'); - expect(A.next().next().previous().previous().any.js).toBe('A'); - expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); - expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); - - expect(A.next().any.js).toBe('B'); - expect(A.next().next().any.js).toBe('C'); - expect(A.next().next().next().any.js).toBe('D'); - expect(A.next().next().next().next().any.js).toBe('E'); - - expect(A.next().next().next().next().next().is_none()).toBe(true); - - expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); - expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); - expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); - } - }); + // test(".Function.Ref(ref)", () => { + // const method = JS.Function.Ref((ref): Ray => new Ray({ + // initial: ref.self.initial.as_arbitrary(), + // terminal: ref.self.terminal.as_arbitrary() + // }).o({ js: ref.type })).as_method; + // + // expect(method(Ray.vertex().as_reference().as_reference())().any.js).toBe(RayType.REFERENCE); + // expect(method(Ray.vertex().as_reference())().any.js).toBe(RayType.VERTEX); + // expect(method(Ray.initial().as_reference())().any.js).toBe(RayType.INITIAL); + // expect(method(Ray.terminal().as_reference())().any.js).toBe(RayType.TERMINAL); + // + // const a = Ray.vertex().o({ js: 'A'}).as_reference(); + // const b = Ray.vertex().o({ js: 'B'}).as_reference(); + // + // // TODO What about method(a)(b)(c)... :thinking: + // expect(method(a)(b).initial.any.js).toBe('A'); + // expect(method(a)(b).terminal.any.js).toBe('B'); + // expect(method(a)(b).type).toBe(RayType.VERTEX); + // }); + // test(".Function.WithMemory", () => { + // const square = JS.Function.WithMemory( + // previous => previous.any.js * previous.any.js, + // ); + // + // let vertex = square.as_ray(Ray.vertex()).self.o({ js: 2 }).as_reference(); + // + // expect(vertex.previous().is_none()).toBe(true); + // + // expect(vertex.any.js).toBe(2); + // expect(vertex.next().any.js).toBe(4); + // expect(vertex.next().next().any.js).toBe(16); + // expect(vertex.next().next().previous().any.js).toBe(4); + // expect(vertex.next().next().previous().previous().any.js).toBe(2); + // + // expect(vertex.next().next().next().any.js).toBe(256); + // expect(vertex.next().next().next().next().any.js).toBe(65536); + // }); + // test(".Function.Reversible", () => { + // const exp2 = JS.Function.Reversible( + // previous => Math.log(previous.any.js) / Math.log(2), + // previous => Math.pow(previous.any.js, 2), + // ); + // + // let vertex = exp2.as_ray(Ray.vertex()).self.o({ js: 2 }).as_reference(); + // + // expect(vertex.previous().any.js).toBe(1); + // + // expect(vertex.any.js).toBe(2); + // expect(vertex.next().any.js).toBe(4); + // expect(vertex.next().next().any.js).toBe(16); + // expect(vertex.next().next().previous().any.js).toBe(4); + // expect(vertex.next().next().previous().previous().any.js).toBe(2); + // + // expect(vertex.next().next().next().any.js).toBe(256); + // expect(vertex.next().next().next().next().any.js).toBe(65536); + // }); + // test(".Object", () => { + // const ray = JS.Object({ + // a: 'b', + // position: [0, 1, 2], + // func: () => 'c' + // }); + // + // expect(ray.any.a).toBe('b'); + // expect(ray.any.undefinedProperty).toBe(undefined); + // expect(() => ray.any.undefinedFunction()).toThrow(); + // expect(ray.any.position).toEqual([0, 1, 2]); + // expect(ray.any.func()).toBe('c'); + // }); + // test(".Boolean", () => { + // const _false = JS.Boolean(false); + // const _true = JS.Boolean(true); + // + // expect(_false.any.js).toBe(false); + // expect(_true.any.js).toBe(true); + // + // expect(_false.next().any.js).toBe(true); + // expect(_false.previous().is_none()).toBe(true); + // + // expect(_true.next().is_none()).toBe(true); + // expect(_true.previous().any.js).toBe(false); + // }); + // test(".Bit", () => { + // const _false = JS.Bit(false); + // const _true = JS.Bit(true); + // + // expect(_false.any.js).toBe(false); + // expect(_true.any.js).toBe(true); + // + // expect(_false.next().any.js).toBe(true); + // expect(_false.previous().is_none()).toBe(true); + // + // expect(_true.next().is_none()).toBe(true); + // expect(_true.previous().any.js).toBe(false); + // }); + // test(".Iterable", () => { + // const iterable = JS.Iterable(['A', 'B', 'C', 'D', 'E']); + // + // expect(iterable.type).toBe(RayType.INITIAL); + // + // const A = iterable.follow(); + // + // expect(A.any.js).toBe('A'); + // expect(A.previous().is_none()).toBe(true); + // + // expect(A.next().previous().any.js).toBe('A'); + // expect(A.next().next().previous().previous().any.js).toBe('A'); + // expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); + // expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); + // + // expect(A.next().any.js).toBe('B'); + // expect(A.next().next().any.js).toBe('C'); + // expect(A.next().next().next().any.js).toBe('D'); + // expect(A.next().next().next().next().any.js).toBe('E'); + // + // expect(A.next().next().next().next().next().is_none()).toBe(true); + // + // expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); + // expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); + // expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); + // }); + // test(".Generator", () => { + // function* generator_function(): Generator { + // yield 'A'; + // yield 'B'; + // yield 'C'; + // yield 'D'; + // yield 'E'; + // } + // const generator = JS.Generator(generator_function()); + // + // expect(generator.type).toBe(RayType.INITIAL); + // + // const A = generator.follow(); + // + // expect(A.any.js).toBe('A'); + // expect(A.previous().is_none()).toBe(true); + // + // expect(A.next().previous().any.js).toBe('A'); + // expect(A.next().next().previous().previous().any.js).toBe('A'); + // expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); + // expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); + // + // expect(A.next().any.js).toBe('B'); + // expect(A.next().next().any.js).toBe('C'); + // expect(A.next().next().next().any.js).toBe('D'); + // expect(A.next().next().next().next().any.js).toBe('E'); + // + // expect(A.next().next().next().next().next().is_none()).toBe(true); + // + // expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); + // expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); + // expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); + // }); + // test(".Any", () => { + // + // // .Object + // { + // const ray = JS.Any({ + // a: 'b', + // position: [0, 1, 2], + // func: () => 'c' + // }); + // + // expect(ray.any.a).toBe('b'); + // expect(ray.any.undefinedProperty).toBe(undefined); + // expect(() => ray.any.undefinedFunction()).toThrow(); + // expect(ray.any.position).toEqual([0, 1, 2]); + // expect(ray.any.func()).toBe('c'); + // } + // // .Boolean + // { + // const _false = JS.Any(false); + // const _true = JS.Any(true); + // + // expect(_false.any.js).toBe(false); + // expect(_true.any.js).toBe(true); + // + // expect(_false.next().any.js).toBe(true); + // expect(_false.previous().is_none()).toBe(true); + // + // expect(_true.next().is_none()).toBe(true); + // expect(_true.previous().any.js).toBe(false); + // } + // // .Iterable + // { + // const iterable = JS.Any(['A', 'B', 'C', 'D', 'E']); + // + // expect(iterable.type).toBe(RayType.INITIAL); + // + // const A = iterable.follow(); + // + // expect(A.any.js).toBe('A'); + // expect(A.previous().is_none()).toBe(true); + // + // expect(A.next().previous().any.js).toBe('A'); + // expect(A.next().next().previous().previous().any.js).toBe('A'); + // expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); + // expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); + // + // expect(A.next().any.js).toBe('B'); + // expect(A.next().next().any.js).toBe('C'); + // expect(A.next().next().next().any.js).toBe('D'); + // expect(A.next().next().next().next().any.js).toBe('E'); + // + // expect(A.next().next().next().next().next().is_none()).toBe(true); + // + // expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); + // expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); + // expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); + // } + // // .Generator + // { + // function* generator_function(): Generator { + // yield 'A'; + // yield 'B'; + // yield 'C'; + // yield 'D'; + // yield 'E'; + // } + // const generator = JS.Any(generator_function()); + // + // expect(generator.type).toBe(RayType.INITIAL); + // + // const A = generator.follow(); + // + // expect(A.any.js).toBe('A'); + // expect(A.previous().is_none()).toBe(true); + // + // expect(A.next().previous().any.js).toBe('A'); + // expect(A.next().next().previous().previous().any.js).toBe('A'); + // expect(A.next().next().next().previous().previous().previous().any.js).toBe('A'); + // expect(A.next().next().next().next().previous().previous().previous().previous().any.js).toBe('A'); + // + // expect(A.next().any.js).toBe('B'); + // expect(A.next().next().any.js).toBe('C'); + // expect(A.next().next().next().any.js).toBe('D'); + // expect(A.next().next().next().next().any.js).toBe('E'); + // + // expect(A.next().next().next().next().next().is_none()).toBe(true); + // + // expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); + // expect([...A.next().next().all().js]).toEqual(['C', 'D', 'E']); + // expect([...A.next().next().next().next().all(Ray.directions.previous).js]).toEqual(['E', 'D', 'C', 'B', 'A']); + // } + // }); }); diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts index 6b28a98..6146ace 100644 --- a/src/@orbitmines/explorer/JS.ts +++ b/src/@orbitmines/explorer/JS.ts @@ -1,241 +1,95 @@ -import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; +import {NotImplementedError} from "./errors/errors"; import _ from "lodash"; -import {AbstractDirectionality, Ray, RayType} from "./Ray"; +import Ray, {Rays} from "./Ray"; /** + * A JavaScript interface for Rays. * - * Important to remember this is just one particular structure to which it can be mapped, there are probably many (TODO infinitely?) others. - * - * Not to be considered as a perfect mapping of JavaScript functionality - merely a practical one. + * NOTE: + * - Not to be considered as a perfect mapping of JavaScript functionality - merely a practical one. + * - Important to remember that this is just one particular mapping, there are probably 'many, ..., infinitely' others. */ namespace JS { export type ParameterlessFunction = () => T; export type ParameterlessConstructor = new () => T; export type Constructor = new (...args: any[]) => T; - export type Implementation = (ref: T) => T; + export type FunctionImpl = (ref: T) => T; + export type Recursive = (T | Recursive)[]; + + export type Method = (...other: Recursive) => TResult; - export type Arbitrary = ParameterlessFunction; + export type FunctionConstructor = + Ray + | ParameterlessFunction + | Function; - export type Recursive = (T | Recursive)[]; - export type Method = (...other: Recursive) => T; + export type Interface = { + [TKey in keyof T]: T[TKey] extends JS.Function + ? JS.Method + : never; + } /** * This allows automatic conversion between "JavaScript functions/.../generators" and Rays. * * TODO: Is there some equivalent of this in computer science??? category theory?? */ - export class Function = Ray> { // TODO: Ray could extend Function - - private readonly step: Implementation; + export class Function { // TODO: Ray could extend Function - constructor(step: JS.Implementation) { - this.step = step; - } - - static Any = = Ray>(...args: any[]): Function => { - throw new NotImplementedError(); - } + static New = (constructor: FunctionConstructor) => new Function(constructor); /** - * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] + * Implement a function from the perspective of 'this'. */ - static Ref = = Ray>(impl: (ref: T) => T): Function => { - return new Function(impl); // TODO: THIS SHOULD CHANGE, TO ON VERTEX. + static Self = (impl: (self: Ray) => TResult): Function => { + return Function.New(() => { + throw new NotImplementedError(); + }); } - static Impl = = Ray>(impl: (initial: T, terminal: T) => T): Function => { - return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); - } - // static IgnorantOfInitial = = Ray>(impl: (terminal: T) => T): Function => Function.Impl((_, terminal) => impl(terminal)); - // static IgnorantOfTerminal = = Ray>(impl: (initial: T) => T): Function => Function.Impl((initial, _) => impl(initial)); - // static Ignorant = = Ray>(impl: ParameterlessFunction): Function => Function.Impl(impl); /** - * TODO: Reversible through memory... + * Implement a function from the perspective of 'this' for 'this.self'. */ - static WithMemory = = Ray>(impl: (initial: T, terminal: T) => T): Function => { - // return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); - throw new NotImplementedError(); - } + // static Ref = (impl: (ref: Ray) => TResult): Function => JS.Function.Self(self => impl(self.as_reference())); - /** - * @see "Reversibility after ignoring some difference": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Another%20example%20of%20this%20is%20reversibility - */ - static Reversible = = Ray>( - // @alias('backward') - initial: (ref: T) => T, - // @alias('forward') - terminal: (ref: T) => T, - ): Function => { - // return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); - throw new NotImplementedError(); + static Two = (impl: (a: Ray, b: Ray) => TResult): Function => { + return Function.New(() => { + throw new NotImplementedError(); + }); } /** - * Constructs a class method accepting arbitrary structure. * - * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = [[a1, [[[a2]]], [[[[]]], []]], b, [[[]], [], [c]]].compose = ... */ - as_method = (ref: T): Method => ((...any: Recursive): T => { - if (any === undefined || any.length === 0) - return this.step(ref); - - // TODO: This can be much better... - const first = (recursive?: Recursive): T | undefined => { - if (recursive === undefined) return; - // if (_.isObject(recursive)) return recursive as unknown as Ray; - - for (let r of recursive) { - if (r === undefined) continue; - if (_.isObject(r)) return r as unknown as T; - - // if (r instanceof Ray) - // throw new PreventsImplementationBug(); - - // @ts-ignore - const _first = first(r); - if (_first) - return _first; - } - } - - const _first = first(any); - - if (_first === undefined) - return this.step(ref); - - const pointer = (new Ray({ - // @ts-ignore - initial: () => ref, - // @ts-ignore - terminal: () => _first - })) as unknown as T; - - return this.step(pointer); - - // TODO: ANY CASE - // if (any.length === 1) { - // } - }) - - as_ray = (): Ray => { - throw new NotImplementedError(); + static CachedAfterUse = (constructor: FunctionConstructor): FunctionConstructor => { + return constructor; } - as_generator = (): Generator => { - throw new NotImplementedError(); - } - - } + protected constructor(constructor: FunctionConstructor) { - export const Boolean = (boolean: boolean): Ray => { - // TODO: Could be superpose structure instead of length 2; - // |-false->-true-| (could of course also be reversed) - const _false = Ray.vertex().o({ js: false }).as_reference(); - const _true = Ray.vertex().o({ js: true }).as_reference(); - _false.compose(_true); - - return (boolean ? _true : _false); - } - // export const bit = (bit?: boolean): Arbitrary> => permutation(bit ? 1 : 0, 2); - export const Bit = Boolean; - - export const Iterable = (iterable: Iterable): Ray => JS.Iterator(iterable[Symbol.iterator]()); - - export const Iterator = (iterator: Iterator): Ray => { - // [ |--] - - const next = (previous: Ray, first: boolean = false): Ray => { - const iterator_result = iterator.next(); - const is_terminal = iterator_result.done === true; - - // Clear the terminal function attached to the Iterator. - // TODO: In case of 'is_terminal = true': Could also leave this be, in case JavaScript allows for adding stuff to the iterator even after .done === true; - previous.self.terminal = previous.self.___empty_terminal(); - - if (is_terminal) { - // We're done, this is the end of the iterator - - return Ray.None(); - } - - const current = Ray - .vertex(() => JS.Any(iterator_result.value)) - .o({js: iterator_result.value}) - .as_reference(); - - // Move the iterator to the terminal. - current.self.terminal = () => next(current); - - if (first) { - // Move the iterator's terminal to current. - ray_iterator.self.terminal = () => current.self; - - current.self.initial = () => ray_iterator.self; - - return current; // Answer to INITIAL.terminal is a VERTEX. - } - - // TODO: This is just compose, but without .type checks.. ; FIX ON COMPOSE END for is_reference etc.. - if (previous.follow().type !== RayType.TERMINAL) - throw new PreventsImplementationBug(); - if (current.follow(Ray.directions.previous).type !== RayType.INITIAL) - throw new PreventsImplementationBug(); - - previous.follow().equivalent(current.follow(Ray.directions.previous)); - // TODO: - // previous.compose(current); - - return current.self.initial; // Answer to VERTEX.terminal is an INITIAL. } - const ray_iterator: Ray = new Ray({ - vertex: Ray.None, - terminal: () => next(ray_iterator, true), - }) - .o({ js: iterator }) - .as_reference(); - - return ray_iterator; - } - - export const Generator = (generator: Generator): Ray => JS.Iterable(generator); - - // TODO Could have parallel threads in general. - // export const AsyncGenerator = (generator: AsyncGenerator): Ray => { - // // [ |--] - // return JS.Iterable(generator); - // } - - export const Number = (number: number): Ray => { - throw new NotImplementedError(); - } - - // TODO - export const Object = (object: object): Ray => Ray.vertex().o(object).as_reference(); + call = (self: Ray) => { throw new NotImplementedError(); } - export const Any = (any: any): Ray => { - if (any === null || any === undefined) return JS.Any(any); - if (JS.is_boolean(any)) return JS.Boolean(any); - if (JS.is_number(any)) return JS.Number(any); - if (JS.is_iterable(any)) return JS.Iterable(any); // || is_array(any)) - if (JS.is_function(any)) return JS.Function.Any(any).as_ray(); - if (JS.is_object(any)) return JS.Object(any); + as_method = (self: Ray): Method => { + throw new NotImplementedError(); + } - // TODO - // return JS.Any(any); - return Ray.vertex().o({js: any}).as_reference(); } - export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); - export const is_number = (_object: any): _object is number => _.isNumber(_object); - export const is_object = (_object: any): _object is object => _.isObject(_object); - export const is_iterable = (_object: any): _object is Iterable => Symbol.iterator in Object(_object) && is_function(_object[Symbol.iterator]); - export const is_async_iterable = (_object: any): _object is AsyncIterable => Symbol.asyncIterator in Object(_object); - export const is_array = (_object: any): _object is T[] => _.isArray(_object); - export const is_async = (_object: any) => _.has(_object, 'then') && is_function(_.get(_object, 'then')); // TODO, Just an ugly check - - export const is_error = (_object: any): _object is Error => _.isError(_object); - export const is_function = (_object: any): _object is ((...args: any[]) => any) => _.isFunction(_object); + /** + * JavaScript runtime type checks + */ + export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); + export const is_number = (_object: any): _object is number => _.isNumber(_object); + export const is_object = (_object: any): _object is object => _.isObject(_object); + export const is_iterable = (_object: any): _object is Iterable => Symbol.iterator in Object(_object) && is_function(_object[Symbol.iterator]); + export const is_async_iterable = (_object: any): _object is AsyncIterable => Symbol.asyncIterator in Object(_object) && is_function(_object[Symbol.asyncIterator]); + export const is_array = (_object: any): _object is T[] => _.isArray(_object); + export const is_async = (_object: any) => _.has(_object, 'then') && is_function(_.get(_object, 'then')); // TODO, Just an ugly check + + export const is_error = (_object: any): _object is Error => _.isError(_object); + export const is_function = (_object: any): _object is ((...args: any[]) => any) => _.isFunction(_object); } export default JS; \ No newline at end of file diff --git a/src/@orbitmines/explorer/JS2.ts b/src/@orbitmines/explorer/JS2.ts new file mode 100644 index 0000000..7aabc9d --- /dev/null +++ b/src/@orbitmines/explorer/JS2.ts @@ -0,0 +1,252 @@ +// +// +// +// private readonly step: JS.FunctionImpl; +// +// +// static Any = (...args: any[]): Function => { +// throw new NotImplementedError(); +// } +// +// +// +// /** +// * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] +// */ +// static Ref = (impl: JS.FunctionImpl): Function => { +// return new Function(impl); // TODO: THIS SHOULD CHANGE, TO ON VERTEX. +// } +// static Impl = (impl: (initial: T, terminal: T) => T): Function => { +// return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); +// } +// // static IgnorantOfInitial = = Ray>(impl: (terminal: T) => T): Function => Function.Impl((_, terminal) => impl(terminal)); +// // static IgnorantOfTerminal = = Ray>(impl: (initial: T) => T): Function => Function.Impl((initial, _) => impl(initial)); +// // static Ignorant = = Ray>(impl: ParameterlessFunction): Function => Function.Impl(impl); +// +// /** +// * TODO: Reversible through memory... +// */ +// static WithMemory = ( +// apply: (previous: Ray) => Ray | any +// ): Function => { +// // return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); +// +// return { +// as_ray: (ref: Ray = Ray.None()) => { +// const next = (previous: Ray, first: boolean = false): Ray => { +// const result = apply(previous); +// const is_terminal = result instanceof Ray ? +// result.is_none() || (result.is_terminal() && result.self.is_none()) +// : false; +// +// // Clear the terminal function attached to the Iterator. +// // TODO: In case of 'is_terminal = true': Could also leave this be, in case JavaScript allows for adding stuff to the iterator even after .done === true; +// previous.self.terminal = previous.self.___empty_terminal(); +// +// if (is_terminal) { +// // We're done, this is the end of the iterator +// +// return Ray.None(); +// } +// +// const current = Ray +// .vertex(() => result instanceof Ray ? result.self : JS.Any(result)) // TODO test +// .o(result instanceof Ray ? {} : { js: result }) +// .as_reference(); +// +// // Move the iterator to the terminal. +// current.self.terminal = () => next(current); +// +// if (first) { +// // Move the iterator's terminal to current. +// previous.self.terminal = () => current.self; +// +// current.self.initial = () => previous.self; +// +// return current; // Answer to INITIAL.terminal is a VERTEX. +// } +// +// // // TODO: This is just compose, but without .type checks.. ; FIX ON COMPOSE END for is_reference etc.. +// // if (previous.follow().type !== RayType.TERMINAL) +// // throw new PreventsImplementationBug(); +// // if (current.follow(Ray.directions.previous).type !== RayType.INITIAL) +// // throw new PreventsImplementationBug(); +// // +// // previous.follow().equivalent(current.follow(Ray.directions.previous)); +// previous.compose(current); +// +// return current.self.initial; // Answer to VERTEX.terminal is an INITIAL. +// } +// +// if (ref.is_none()) { +// const ray: Ray = new Ray({ +// vertex: Ray.None, +// terminal: () => next(ray, true), +// }).as_reference(); +// +// return ray; +// } else { +// const initial_vertex = Ray.vertex(() => ref.self).as_reference(); +// +// initial_vertex.self.terminal = () => next(initial_vertex); +// +// return initial_vertex; +// } +// } +// } as Function; +// } +// +// /** +// * @see "Reversibility after ignoring some difference": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Another%20example%20of%20this%20is%20reversibility +// * @see "More accurately phrased as the assumption of Reversibility: with the potential of being violated.": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Assumptions%20%26%20Assumption%20Violation +// */ +// static Reversible = = Ray>( +// // @alias('backward') +// initial: (ref: Ray) => Ray | any, +// // @alias('forward') +// terminal: (ref: Ray) => Ray | any, +// ): Function => { +// // return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); +// +// return { +// as_ray: (ref: Ray = Ray.None()): Ray => { +// if (ref.is_none()) +// throw new NotImplementedError(); +// +// const next = (previous: Ray, direction: (ref: Ray) => Ray | any): Ray => { +// const result = direction(previous); +// +// // TODO: COuld do this in place. +// const current = Ray +// .vertex(() => result instanceof Ray ? result.self : JS.Any(result)) +// .o(result instanceof Ray ? {} : { js: result }) +// .as_reference(); +// +// current.self.initial.self = () => next(current, initial); +// current.self.terminal.self = () => next(current, terminal); +// +// return current.self.initial; +// } +// +// +// const initial_vertex = Ray.vertex(() => ref.self).as_reference(); +// +// // const initial_vertex = Ray.vertex(() => ref.self).as_reference(); +// initial_vertex.self.initial.self = () => next(initial_vertex, initial); +// initial_vertex.self.terminal.self = () => next(initial_vertex, terminal); +// +// return initial_vertex; +// } +// } as Function; +// } +// +// /** +// * Constructs a class method accepting arbitrary structure. +// * +// * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = [[a1, [[[a2]]], [[[[]]], []]], b, [[[]], [], [c]]].compose = ... +// */ +// as_method = (ref: Ray): Method => ((...any: Recursive): TResult => { +// if (any === undefined || any.length === 0) +// return this.step(ref); +// +// // TODO: This can be much better... +// const first = (recursive?: Recursive): T | undefined => { +// if (recursive === undefined) return; +// // if (_.isObject(recursive)) return recursive as unknown as Ray; +// +// for (let r of recursive) { +// if (r === undefined) continue; +// if (_.isObject(r)) return r as unknown as T; +// +// // if (r instanceof Ray) +// // throw new PreventsImplementationBug(); +// +// // @ts-ignore +// const _first = first(r); +// if (_first) +// return _first; +// } +// } +// +// const _first = first(any); +// +// if (_first === undefined) +// return this.step(ref); +// +// const pointer = (new Ray({ +// // @ts-ignore +// initial: () => ref, +// // @ts-ignore +// terminal: () => _first +// })) as unknown as T; +// +// return this.step(pointer); +// +// // TODO: ANY CASE +// // if (any.length === 1) { +// // } +// }) +// +// as_ray = (initial: Ray = Ray.None()): Ray => { +// throw new NotImplementedError(); +// } +// +// as_generator = (): Generator => { +// throw new NotImplementedError(); +// } +// +// } +// +// export const Boolean = (boolean: boolean): Ray => { +// // TODO: Could be superpose structure instead of length 2; +// // |-false->-true-| (could of course also be reversed) +// const _false = Ray.vertex().o({ js: false }).as_reference(); +// const _true = Ray.vertex().o({ js: true }).as_reference(); +// _false.compose(_true); +// +// return (boolean ? _true : _false); +// } +// // export const bit = (bit?: boolean): Arbitrary> => permutation(bit ? 1 : 0, 2); +// export const Bit = Boolean; +// +// export const Iterable = (iterable: Iterable): Ray => JS.Iterator(iterable[Symbol.iterator]()); +// +// export const Iterator = (iterator: Iterator): Ray => { +// // [ |--] +// +// return JS.Function.WithMemory(previous => { +// const iterator_result = iterator.next(); +// +// return iterator_result.done !== true ? iterator_result.value : Ray.None(); +// }).as_ray(); +// } +// +// export const Generator = (generator: Generator): Ray => JS.Iterable(generator); +// +// // TODO Could have parallel threads in general. +// // export const AsyncGenerator = (generator: AsyncGenerator): Ray => { +// // // [ |--] +// // return JS.Iterable(generator); +// // } +// +// export const Number = (number: number): Ray => { +// throw new NotImplementedError(); +// } +// +// // TODO +// export const Object = (object: object): Ray => Ray.vertex().o(object).as_reference(); +// +// export const Any = (any: any): Ray => { +// if (any === null || any === undefined) return JS.Any(any); +// if (JS.is_boolean(any)) return JS.Boolean(any); +// // if (JS.is_number(any)) return JS.Number(any); TODO +// if (JS.is_iterable(any)) return JS.Iterable(any); // || is_array(any)) +// if (JS.is_function(any)) return JS.Function.Any(any).as_ray(); +// if (JS.is_object(any)) return JS.Object(any); +// +// // TODO +// // return JS.Any(any); +// return Ray.vertex().o({js: any}).as_reference(); +// } +// +// } diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 4cf0cf9..846e89b 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -1,1713 +1,1773 @@ -import {Ray, RayType} from "./Ray"; +import Ray, {Rays} from "./Ray"; describe("Ray", () => { - test("[A, B, C].copy", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); + test(".is_orbit", () => { + const a = Rays.New(); + const b = Rays.New(); - A.compose(B).compose(C); - - expect(() => A.copy()).toThrow(); //TODO - // const copy = A.copy(); - // expect(A.has_previous()).toBe(false); - - // expect(copy.has_previous()).toBe(false); - }); - test("[A, [B, C]]", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - /** - * [--A--] [--| ] - * [ |--] [--B--] - */ - A.compose(B); - - /** - * [--A--] [--| ] - * [ |--] [--B--] - * | - * [ |--] [--C--] - */ - A.compose(C); - - expect(A.follow().type).toEqual(RayType.TERMINAL); - expect(A.follow().dereference.type).toEqual(RayType.VERTEX); - expect([...A.follow().dereference].map(ref => ref.self.follow_direction().any.js)).toEqual(['A', 'B', 'C']); - expect([...A.all().js]).toEqual(['A', 'B', 'C']); - // expect([...A].map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); - - - }); - test(".vertex.#.delete", () => { - const A_vertex = Ray.vertex().o({ js: 'A' }); - const A_ref = A_vertex.as_reference().o({ js: 'A.#' }); - - expect(A_vertex.is_none()).toBe(false); - expect(A_ref.follow().is_none()).toBe(false); - expect(A_ref.follow(Ray.directions.previous).is_none()).toBe(false); - expect(A_ref.any.js).toBe('A'); - expect(A_ref.is_none()).toBe(false); - - A_ref.delete(); - - expect(A_vertex.is_none()).toBe(true); - expect(A_vertex.follow().is_none()).toBe(true); - expect(A_vertex.follow(Ray.directions.previous).is_none()).toBe(true); - expect(A_vertex.any.js).toBe(undefined); - expect(A_ref.is_none()).toBe(true); - }); - test("[A, B, C, D, E].all().js", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); - - A.compose(B).compose(C).compose(D).compose(E); - - expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); - }); - test("[A, B, C, D, E].all() ; -= / +=", () => { - const A = Ray.vertex().o({ js: 'A', value: 0 }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B', value: 1 }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C', value: 2 }).as_reference().o({ js: 'C.#' }); - const D = Ray.vertex().o({ js: 'D', value: 3 }).as_reference().o({ js: 'D.#' }); - const E = Ray.vertex().o({ js: 'E', value: 4 }).as_reference().o({ js: 'E.#' }); - - A.compose(B).compose(C).compose(D).compose(E); - - A.all().value = (value: number) => value - 3; - expect([...A.all().value]).toEqual([-3, -2, -1, 0, 1]); - - C.all().value = (value: number) => value + 10; - expect([...A.all().value]).toEqual([-3, -2, 9, 10, 11]); - - D.all(Ray.directions.previous).value = (value: number) => value - 50; - expect([...A.all().value]).toEqual([-53, -52, -41, -40, 11]); - }); - test("[A, B, C, D, E].___next()", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); - - A.compose(B).compose(C).compose(D).compose(E); - - expect([...A.___next()].map(ref => ref.any.js)).toEqual(['A', 'B', 'C', 'D', 'E']); - expect(A.last().any.js).toEqual('E'); - expect(D.first().any.js).toEqual('A'); - }); - test("[A, B, C, D, E].___traverse()", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); - - A.compose(B).compose(C).compose(D).compose(E); - - expect([...A.___traverse()].map(pointer => - [pointer.terminal.is_none(), pointer.initial.type, pointer.terminal.type, pointer.initial.any.js] - )).toEqual([ - [false, RayType.VERTEX, RayType.TERMINAL, 'A'], - [false, RayType.TERMINAL, RayType.INITIAL, undefined], - [false, RayType.INITIAL, RayType.VERTEX, undefined], - [false, RayType.VERTEX, RayType.TERMINAL, 'B'], - [false, RayType.TERMINAL, RayType.INITIAL, undefined], - [false, RayType.INITIAL, RayType.VERTEX, undefined], - [false, RayType.VERTEX, RayType.TERMINAL, 'C'], - [false, RayType.TERMINAL, RayType.INITIAL, undefined], - [false, RayType.INITIAL, RayType.VERTEX, undefined], - [false, RayType.VERTEX, RayType.TERMINAL, 'D'], - [false, RayType.TERMINAL, RayType.INITIAL, undefined], - [false, RayType.INITIAL, RayType.VERTEX, undefined], - [false, RayType.VERTEX, RayType.TERMINAL, 'E'], - [true, RayType.TERMINAL, RayType.VERTEX, undefined], // vertex is Ray.None - ]); - }); - test("[A, [B, C, D]].___traverse()", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - // - // A.compose(B); - // A.compose(C); - - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const A_terminal = A.follow(); - const B_initial = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }).follow(Ray.directions.previous); - const C_initial = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }).follow(Ray.directions.previous); - const D_initial = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }).follow(Ray.directions.previous); - - A_terminal.equivalent(B_initial); - A_terminal.equivalent(C_initial); - A_terminal.equivalent(D_initial); - - expect([...A.___traverse()].map(pointer => - [pointer.terminal.is_none(), pointer.initial.type, pointer.terminal.type, pointer.terminal.is_boundary() ? pointer.terminal.follow_direction().any.js : undefined] - )).toEqual([ - [false, RayType.VERTEX, RayType.TERMINAL, 'A'], - [false, RayType.TERMINAL, RayType.VERTEX, undefined], - // [true, RayType.VERTEX, RayType.VERTEX, undefined], - ]); - }); - test("[A, B, C].next()", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - A.compose(B).compose(C); - - // let pointer = A.step(Ray.directions.next()(A)); - - let pointer = new Ray({ - initial: () => A, - terminal: () => Ray.directions.next(A), - }); - - /** - * ____________ - * [ |--] [--| ][ |--] [--| ][ |--] [--| ] - * [--A--] [--B--] [--C--] - */ - - expect(pointer.initial.any.js).toBe('A'); - - expect(pointer.initial.type).toBe(RayType.VERTEX); - expect(pointer.terminal.type).toBe(RayType.TERMINAL); - - pointer = pointer.step(); - - /** - * ______________ - * [ |--] [--| ][ |--] [--| ][ |--] [--| ] - * [--A--] [--B--] [--C--] - */ - expect(pointer.initial.type).toBe(RayType.TERMINAL); - expect(pointer.terminal.type).toBe(RayType.INITIAL); - - pointer = pointer.step(); - - /** - * ____________ - * [ |--] [--| ][ |--] [--| ][ |--] [--| ] - * [--A--] [--B--] [--C--] - */ - expect(pointer.initial.type).toBe(RayType.INITIAL); - expect(pointer.terminal.type).toBe(RayType.VERTEX); - expect(pointer.terminal.any.js).toBe('B'); - - pointer = pointer.step(); - - /** - * ____________ - * [ |--] [--| ][ |--] [--| ][ |--] [--| ] - * [--A--] [--B--] [--C--] - */ - expect(pointer.initial.type).toBe(RayType.VERTEX); - expect(pointer.terminal.type).toBe(RayType.TERMINAL); - - pointer = pointer.step(); - - /** - * ______________ - * [ |--] [--| ][ |--] [--| ][ |--] [--| ] - * [--A--] [--B--] [--C--] - */ - expect(pointer.initial.type).toBe(RayType.TERMINAL); - expect(pointer.terminal.type).toBe(RayType.INITIAL); - - pointer = pointer.step(); - - /** - * ____________ - * [ |--] [--| ][ |--] [--| ][ |--] [--| ] - * [--A--] [--B--] [--C--] - */ - expect(pointer.initial.type).toBe(RayType.INITIAL); - expect(pointer.terminal.type).toBe(RayType.VERTEX); - expect(pointer.terminal.any.js).toBe('C'); - - pointer = pointer.step(); - - /** - * ____________ - * [ |--] [--| ][ |--] [--| ][ |--] [--| ] - * [--A--] [--B--] [--C--] - */ - expect(pointer.initial.type).toBe(RayType.VERTEX); - expect(pointer.terminal.type).toBe(RayType.TERMINAL); - - pointer = pointer.step(); - - /** - * _______ - * [ |--] [--| ][ |--] [--| ][ |--] [--| ] - * [--A--] [--B--] [--C--] - */ - expect(pointer.initial.type).toBe(RayType.TERMINAL); - // expect(pointer.terminal.type).toBe(RayType.TERMINAL); ?? - expect(pointer.terminal.is_none()).toBe(true); - }); - test("[A, B, C].previous()", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - A.compose(B).compose(C); - - // let pointer = A.step(Ray.directions.next()(A)); - - let pointer = new Ray({ - initial: () => C, - terminal: () => Ray.directions.previous(C), - }); - - expect(pointer.initial.any.js).toBe('C'); - - expect(pointer.initial.type).toBe(RayType.VERTEX); - expect(pointer.terminal.type).toBe(RayType.INITIAL); - - pointer = pointer.step(); - - expect(pointer.initial.type).toBe(RayType.INITIAL); - expect(pointer.terminal.type).toBe(RayType.TERMINAL); - - pointer = pointer.step(); - - expect(pointer.initial.type).toBe(RayType.TERMINAL); - expect(pointer.terminal.type).toBe(RayType.VERTEX); - expect(pointer.terminal.any.js).toBe('B'); - - pointer = pointer.step(); - - expect(pointer.initial.type).toBe(RayType.VERTEX); - expect(pointer.terminal.type).toBe(RayType.INITIAL); - - pointer = pointer.step(); - - expect(pointer.initial.type).toBe(RayType.INITIAL); - expect(pointer.terminal.type).toBe(RayType.TERMINAL); - - pointer = pointer.step(); - - expect(pointer.initial.type).toBe(RayType.TERMINAL); - expect(pointer.terminal.type).toBe(RayType.VERTEX); - expect(pointer.terminal.any.js).toBe('A'); - - pointer = pointer.step(); - - expect(pointer.initial.type).toBe(RayType.VERTEX); - expect(pointer.terminal.type).toBe(RayType.INITIAL); - - pointer = pointer.step(); - - expect(pointer.initial.type).toBe(RayType.INITIAL); - // expect(pointer.terminal.type).toBe(RayType.TERMINAL); ?? - expect(pointer.terminal.is_none()).toBe(true); - }); - test("[A, B, C][.has_next(), .has_previous()]", () => { - const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); - const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); - const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); - - A.compose(B).compose(C); - - expect(A.has_next()).toBe(true); - expect(A.has_next(Ray.directions.next)).toBe(true); - expect(A.has_next(Ray.directions.previous)).toBe(false); - expect(A.has_previous()).toBe(false); - expect(A.has_previous(Ray.directions.previous)).toBe(false); - expect(A.has_previous(Ray.directions.next)).toBe(true); - - expect(B.has_next()).toBe(true); - expect(B.has_next(Ray.directions.next)).toBe(true); - expect(B.has_next(Ray.directions.previous)).toBe(true); - expect(B.has_previous()).toBe(true); - expect(B.has_previous(Ray.directions.previous)).toBe(true); - expect(B.has_previous(Ray.directions.next)).toBe(true); - - expect(C.has_next()).toBe(false); - expect(C.has_next(Ray.directions.next)).toBe(false); - expect(C.has_next(Ray.directions.previous)).toBe(true); - expect(C.has_previous()).toBe(true); - expect(C.has_previous(Ray.directions.previous)).toBe(true); - expect(C.has_previous(Ray.directions.next)).toBe(false); + expect(a.is_orbit(a)).toBe(true); + expect(b.is_orbit(b)).toBe(true); + expect(a.is_orbit(b)).toBe(false); }); - test("[A, B, C][.last(), .first()]", () => { - const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); - const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); - const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); - - A.compose(B).compose(C); - - expect(A.first().any.js).toBe('A'); - expect(B.first().any.js).toBe('A'); - expect(C.first().any.js).toBe('A'); - - expect(A.last().any.js).toBe('C'); - expect(B.last().any.js).toBe('C'); - expect(C.last().any.js).toBe('C'); - }); - test("[A, B, C][.at()]", () => { - const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); - const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); - const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); - - A.compose(B).compose(C); - - expect(A.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); - expect(A.at(-100).is_none()).toBe(true); - expect(A.at(-1).is_none()).toBe(true); - expect(A.at(0).any.js).toBe('A'); - expect(A.at(1).any.js).toBe('B'); - expect(A.at(2).any.js).toBe('C'); - expect(A.at(3).is_none()).toBe(true); - expect(A.at(100).is_none()).toBe(true); - expect(A.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); - - expect(B.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); - expect(B.at(-100).is_none()).toBe(true); - expect(B.at(-2).is_none()).toBe(true); - expect(B.at(-1).any.js).toBe('A'); - expect(B.at(0).any.js).toBe('B'); - expect(B.at(1).any.js).toBe('C'); - expect(B.at(2).is_none()).toBe(true); - expect(B.at(100).is_none()).toBe(true); - expect(B.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); - - expect(C.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); - expect(C.at(-100).is_none()).toBe(true); - expect(C.at(-3).is_none()).toBe(true); - expect(C.at(-2).any.js).toBe('A'); - expect(C.at(-1).any.js).toBe('B'); - expect(C.at(0).any.js).toBe('C'); - expect(C.at(1).is_none()).toBe(true); - expect(C.at(100).is_none()).toBe(true); - expect(C.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); - }); - test(".permutation", () => { - const A = Ray.permutation(0, 3); - const B = Ray.permutation(1, 3); - const C = Ray.permutation(2, 3); - - expect(A.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); - expect(A.at(-100).is_none()).toBe(true); - expect(A.at(-1).is_none()).toBe(true); - - expect(A.at(0).is_some()).toBe(true); - expect(A.at(1).is_some()).toBe(true); - expect(A.at(2).is_some()).toBe(true); - - expect(A.at(3).is_none()).toBe(true); - expect(A.at(100).is_none()).toBe(true); - expect(A.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); - - - expect(B.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); - expect(B.at(-100).is_none()).toBe(true); - expect(B.at(-2).is_none()).toBe(true); - - expect(B.at(-1).is_some()).toBe(true); - expect(B.at(0).is_some()).toBe(true); - expect(B.at(1).is_some()).toBe(true); - - expect(B.at(2).is_none()).toBe(true); - expect(B.at(100).is_none()).toBe(true); - expect(B.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); - - - expect(C.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); - expect(C.at(-100).is_none()).toBe(true); - expect(C.at(-3).is_none()).toBe(true); - - expect(C.at(-2).is_some()).toBe(true); - expect(C.at(-1).is_some()).toBe(true); - expect(C.at(0).is_some()).toBe(true); - - expect(C.at(1).is_none()).toBe(true); - expect(C.at(100).is_none()).toBe(true); - expect(C.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); - }); - test("[A, B, C][.next(), .previous()]", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - expect(A.next().is_none()).toBe(true); - expect(A.previous().is_none()).toBe(true); - - A.compose(B).compose(C); - - expect(A.next().is_none()).toBe(false); - expect(A.previous().is_none()).toBe(true); - - expect(A.next().next().next().is_none()).toBe(true); - - expect(A.next().type).toBe(RayType.VERTEX); - // expect(current.next().any.js).toBe('B.#'); TODO, maybe the ref?? - expect(A.next().any.js).toBe('B'); - - expect(A.next().next().type).toBe(RayType.VERTEX); - expect(A.next().next().any.js).toBe('C'); - - expect(A.next().previous().any.js).toBe('A'); - expect(A.next().next().previous().any.js).toBe('B'); - expect(A.next().next().previous().previous().any.js).toBe('A'); - expect(A.next().previous().next().next().previous().any.js).toBe('B'); - expect(A.next().previous().next().next().previous().next().any.js).toBe('C'); - }); - test("[A, B, C], [X, Y, Z] ; C.compose(X)", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); - const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); - const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); - - A.compose(B).compose(C); - X.compose(Y).compose(Z); - - C.compose(X); - - expect([...A.all().js]).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); - expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); - expect([...X.all(Ray.directions.previous).js]).toEqual(['X', 'C', 'B', 'A']); - expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); - }); - // test("[A, B, C], [X, Y, Z] ; B.compose(X)", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - // - // const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); - // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); - // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); - // - // A.compose(B).compose(C); - // X.compose(Y).compose(Z); - // - // B.compose(X); - // - // // expect([...A.all().js]).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); - // // expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); - // // expect([...X.all(Ray.directions.previous).js]).toEqual(['X', 'C', 'B', 'A']); - // // expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); - // }); - test("[A, [X, Y, Z].initial, B, C][.next(), .previous()]", () => { - // /** - // * | | - // * |-- A --| |-- B --|-- C --| - // * | \ | - // * |-- X --| - // * | \ | - // * |-- Y --| - // * | \ | - // * |-- Z --| - // * | \ | (Destroys the '\' connections) TODO: This should be optional/more complexly constructed - // */ - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - // - // const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); - // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); - // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); - // - // X.compose(Y).compose(Z); - // - // const ret = A.compose(X.follow(Ray.directions.previous)); - - - - // /** - // * | - // * |-- A --| - // * | \ <-- '\' is 'ret' - // * |-- X --| - // * | \ - // * |-- Y --| - // * | \ - // * |-- Z --| - // * | \ - // */ - // expect(ret.type).toBe(RayType.INITIAL); - // expect(ret.follow().is_none()).toBe(false); - // expect([...ret.follow()].map( - // return_ref => return_ref.type - // )).toEqual([RayType.VERTEX, RayType.VERTEX, RayType.VERTEX]); - // expect([...ret.follow()].map( - // return_ref => return_ref.self.type - // )).toEqual([RayType.TERMINAL, RayType.TERMINAL, RayType.TERMINAL]); - // expect([...ret.follow()].map( - // return_ref => { - // const return_vertex = return_ref.self; - // const terminal = return_vertex.self; - // const continued_vertex = terminal.initial; - // - // return continued_vertex.any.js; - // } - // )).toEqual(['X', 'Y', 'Z']); - // expect([...ret.follow()].map( - // return_ref => { - // const vertex = return_ref.self; - // const terminal = vertex.self; - // - // return terminal.self.as_reference().is_none(); - // } - // )).toEqual([true, true, true]); // From the perspective of the 'terminal' it's ignorant of 'ret'. - // - // expect(A.next().type).toBe(RayType.INITIAL); - // - // /** - // * | | - // * |-- A --| |-- B --|-- C --| - // * | | - // * |-- X --| - // * | | - // * |-- Y --| - // * | | - // * |-- Z --| - // * | | - // */ - // ret.compose(B).compose(C); - // - - }); - // test(".None.#.equivalent(.None.#)", () => { - // const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. - // const B = Ray.None().o({ js: 'B' }).as_reference(); - // - // expect(A.type).toBe(RayType.VERTEX); - // expect(B.type).toBe(RayType.VERTEX); - // - // expect(A.is_none()).toBe(true); - // expect(A.any.js).toBe('A'); - // expect(A.self.any.js).toBe('A'); - // expect(A.self.self.any.js).toBe('A'); - // - // expect(B.is_none()).toBe(true); - // expect(B.any.js).toBe('B'); - // expect(B.self.any.js).toBe('B'); - // expect(B.self.self.any.js).toBe('B'); - // - // A.equivalent(B); - // - // expect(A.type).toBe(RayType.REFERENCE); // Turns A into a reference to B. - // expect(B.type).toBe(RayType.REFERENCE); // Turns B into a reference to A. - // - // expect(A.is_none()).toBe(false); - // expect(A.any.js).toBe('A'); - // expect(A.self.any.js).toBe('B'); - // expect(A.self.self.any.js).toBe('A'); - // - // expect(B.is_none()).toBe(false); - // expect(B.any.js).toBe('B'); - // expect(B.self.any.js).toBe('A'); - // expect(B.self.self.any.js).toBe('B'); - // }); - test(".vertex.#.equivalent(.vertex.#)", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - - expect(A.type).toBe(RayType.VERTEX); - expect(B.type).toBe(RayType.VERTEX); - expect(A.as_reference().any.js).toBe('A.#'); - expect(B.as_reference().any.js).toBe('B.#'); - - expect(A.is_none()).toBe(false); - expect(A.dereference.is_none()).toBe(true); - - expect(B.is_none()).toBe(false); - expect(B.dereference.is_none()).toBe(true); - - A.equivalent(B); - - expect(A.type).toBe(RayType.VERTEX); - expect(A.self.type).toBe(RayType.VERTEX); - expect(A.is_none()).toBe(false); - expect(A.any.js).toBe('A'); - expect(A.self.any.js).toBe('___as_vertex'); - expect(A.self.self.any.js).toBe('A'); - expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B']); - expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - - expect(B.type).toBe(RayType.VERTEX); - expect(B.self.type).toBe(RayType.VERTEX); - expect(B.is_none()).toBe(false); - expect(B.any.js).toBe('B'); - expect(B.self.any.js).toBe('___as_vertex'); - expect(B.self.self.any.js).toBe('B'); - expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B']); - expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - }); - test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y).equiv(J).equiv(R)", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); - const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); - const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); - - const I = Ray.vertex().o({ js: 'I' }).as_reference().o({ js: 'I.#' }); - const J = Ray.vertex().o({ js: 'J' }).as_reference().o({ js: 'J.#' }); - const K = Ray.vertex().o({ js: 'K' }).as_reference().o({ js: 'K.#' }); - - const Q = Ray.vertex().o({ js: 'Q' }).as_reference().o({ js: 'Q.#' }); - const R = Ray.vertex().o({ js: 'R' }).as_reference().o({ js: 'R.#' }); - const S = Ray.vertex().o({ js: 'S' }).as_reference().o({ js: 'S.#' }); - - A.compose(B).compose(C); - X.compose(Y).compose(Z); - I.compose(J).compose(K); - Q.compose(R).compose(S); - - // BEFORE .equivalent - expect([...A.all().js]).toEqual(['A', 'B', 'C']); - expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); - expect([...B.all().js]).toEqual(['B', 'C']); - expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); - expect([...C.all().js]).toEqual(['C']); - expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); - - expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); - expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); - expect([...Y.all().js]).toEqual(['Y', 'Z']); - expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); - expect([...Z.all().js]).toEqual(['Z']); - expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); - - expect([...I.all().js]).toEqual(['I', 'J', 'K']); - expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); - expect([...J.all().js]).toEqual(['J', 'K']); - expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); - expect([...K.all().js]).toEqual(['K']); - expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); - - expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); - expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); - expect([...R.all().js]).toEqual(['R', 'S']); - expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); - expect([...S.all().js]).toEqual(['S']); - expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); - - /** - * Drawing an equivalence between `B -> Y -> J -> R`. (Doesn't need to hold in some more abstract sense, it's just a line) - * | - * [--A--][--B--][--C--] - * | - * [--X--][--Y--][--Z--] - * | - * [--I--][--J--][--K--] - * | - * [--Q--][--R--][--S--] - * | - */ - B.equivalent(Y).equivalent(J).equivalent(R); - - // TODO: Bug is from one empty side. - // TODO: Still one bug, J.# ->, makes the equiv(R) a parallel composition, so something is TERMINAL/INITIAL -> VERTEX - - // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) - expect([...A.all().js]).toEqual(['A', 'B', 'C']); - expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); - expect([...B.all().js]).toEqual(['B', 'C']); - expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); - expect([...C.all().js]).toEqual(['C']); - expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); - - expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); - expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); - expect([...Y.all().js]).toEqual(['Y', 'Z']); - expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); - expect([...Z.all().js]).toEqual(['Z']); - expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); - - expect([...I.all().js]).toEqual(['I', 'J', 'K']); - expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); - expect([...J.all().js]).toEqual(['J', 'K']); - expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); - expect([...K.all().js]).toEqual(['K']); - expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); - - expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); - expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); - expect([...R.all().js]).toEqual(['R', 'S']); - expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); - expect([...S.all().js]).toEqual(['S']); - expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); - - // But they should be connected through their .vertex/.self: - expect(B.dereference.is_none()).toBe(false); - expect(B.dereference.type).toBe(RayType.VERTEX); - expect(B.dereference.self).not.toBe(B.self); - expect(B.dereference.self.any.js).toBe('B'); - expect(B.dereference.any.js).toBe('___as_vertex'); - expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B']); - expect([...B.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); - - expect(Y.dereference.is_none()).toBe(false); - expect(Y.dereference.type).toBe(RayType.VERTEX); - expect(Y.dereference.self).not.toBe(Y.self); - expect(Y.dereference.self.any.js).toBe('Y'); - expect(Y.dereference.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'J', 'R']); - - expect(J.dereference.is_none()).toBe(false); - expect(J.dereference.type).toBe(RayType.VERTEX); - expect(J.dereference.self).not.toBe(J.self); - expect(J.dereference.self.any.js).toBe('J'); - expect(J.dereference.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'Y', 'B']); - expect([...J.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'R']); - - expect(R.dereference.is_none()).toBe(false); - expect(R.dereference.type).toBe(RayType.VERTEX); - expect(R.dereference.self).not.toBe(R.self); - expect(R.dereference.self.any.js).toBe('R'); - expect(R.dereference.any.js).toBe('___as_vertex'); - expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); - expect([...R.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['R']); - }); - test("([ABC], [XYZ], [IJK]]) ; B.equiv(Y).equiv(J)", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); - const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); - const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); - - const I = Ray.vertex().o({ js: 'I' }).as_reference().o({ js: 'I.#' }); - const J = Ray.vertex().o({ js: 'J' }).as_reference().o({ js: 'J.#' }); - const K = Ray.vertex().o({ js: 'K' }).as_reference().o({ js: 'K.#' }); - - A.compose(B).compose(C); - X.compose(Y).compose(Z); - I.compose(J).compose(K); - - // BEFORE .equivalent - expect([...A.all().js]).toEqual(['A', 'B', 'C']); - expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); - expect([...B.all().js]).toEqual(['B', 'C']); - expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); - expect([...C.all().js]).toEqual(['C']); - expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); - - expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); - expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); - expect([...Y.all().js]).toEqual(['Y', 'Z']); - expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); - expect([...Z.all().js]).toEqual(['Z']); - expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); - expect([...I.all().js]).toEqual(['I', 'J', 'K']); - expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); - expect([...J.all().js]).toEqual(['J', 'K']); - expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); - expect([...K.all().js]).toEqual(['K']); - expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); - - /** - * Drawing an equivalence between `B -> Y -> J`. (Doesn't need to hold in some more abstract sense, it's just a line) - * | - * [--A--][--B--][--C--] - * | - * [--X--][--Y--][--Z--] - * | - * [--I--][--J--][--K--] - * | - */ - B.equivalent(Y).equivalent(J); - - // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) - expect([...A.all().js]).toEqual(['A', 'B', 'C']); - expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); - expect([...B.all().js]).toEqual(['B', 'C']); - expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); - expect([...C.all().js]).toEqual(['C']); - expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); - - expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); - expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); - expect([...Y.all().js]).toEqual(['Y', 'Z']); - expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); - expect([...Z.all().js]).toEqual(['Z']); - expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); - - expect([...I.all().js]).toEqual(['I', 'J', 'K']); - expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); - expect([...J.all().js]).toEqual(['J', 'K']); - expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); - expect([...K.all().js]).toEqual(['K']); - expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); - - // But they should be connected through their .vertex/.self: - expect(B.dereference.is_none()).toBe(false); - expect(B.dereference.type).toBe(RayType.VERTEX); - expect(B.dereference.self).not.toBe(B.self); - expect(B.dereference.self.any.js).toBe('B'); - expect(B.dereference.any.js).toBe('___as_vertex'); - expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(1); - expect([...B.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'Y', 'J']); - - expect(Y.dereference.is_none()).toBe(false); - expect(Y.dereference.type).toBe(RayType.VERTEX); - expect(Y.dereference.self).not.toBe(Y.self); - expect(Y.dereference.self.any.js).toBe('Y'); - expect(Y.dereference.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'J']); - - expect(J.dereference.is_none()).toBe(false); - expect(J.dereference.type).toBe(RayType.VERTEX); - expect(J.dereference.self).not.toBe(J.self); - expect(J.dereference.self.any.js).toBe('J'); - expect(J.dereference.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'Y', 'B']); - expect([...J.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['J']); - }); - test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y) ; J.equiv(J) ; Y.equiv(J)", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); - const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); - const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); - - const I = Ray.vertex().o({ js: 'I' }).as_reference().o({ js: 'I.#' }); - const J = Ray.vertex().o({ js: 'J' }).as_reference().o({ js: 'J.#' }); - const K = Ray.vertex().o({ js: 'K' }).as_reference().o({ js: 'K.#' }); - - const Q = Ray.vertex().o({ js: 'Q' }).as_reference().o({ js: 'Q.#' }); - const R = Ray.vertex().o({ js: 'R' }).as_reference().o({ js: 'R.#' }); - const S = Ray.vertex().o({ js: 'S' }).as_reference().o({ js: 'S.#' }); - - A.compose(B).compose(C); - X.compose(Y).compose(Z); - I.compose(J).compose(K); - Q.compose(R).compose(S); - - // BEFORE .equivalent - expect([...A.all().js]).toEqual(['A', 'B', 'C']); - expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); - expect([...B.all().js]).toEqual(['B', 'C']); - expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); - expect([...C.all().js]).toEqual(['C']); - expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); - - expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); - expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); - expect([...Y.all().js]).toEqual(['Y', 'Z']); - expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); - expect([...Z.all().js]).toEqual(['Z']); - expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); - - expect([...I.all().js]).toEqual(['I', 'J', 'K']); - expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); - expect([...J.all().js]).toEqual(['J', 'K']); - expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); - expect([...K.all().js]).toEqual(['K']); - expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); - - expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); - expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); - expect([...R.all().js]).toEqual(['R', 'S']); - expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); - expect([...S.all().js]).toEqual(['S']); - expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); - - /** - * Drawing an equivalence between `B -> Y -> J -> R`. (Doesn't need to hold in some more abstract sense, it's just a line) - * | - * [--A--][--B--][--C--] - * | - * [--X--][--Y--][--Z--] - * | - * [--I--][--J--][--K--] - * | - * [--Q--][--R--][--S--] - * | - */ - B.equivalent(Y); - J.equivalent(R); - Y.equivalent(J); - - // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) - expect([...A.all().js]).toEqual(['A', 'B', 'C']); - expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); - expect([...B.all().js]).toEqual(['B', 'C']); - expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); - expect([...C.all().js]).toEqual(['C']); - expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); - - expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); - expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); - expect([...Y.all().js]).toEqual(['Y', 'Z']); - expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); - expect([...Z.all().js]).toEqual(['Z']); - expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); - - expect([...I.all().js]).toEqual(['I', 'J', 'K']); - expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); - expect([...J.all().js]).toEqual(['J', 'K']); - expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); - expect([...K.all().js]).toEqual(['K']); - expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); - - expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); - expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); - expect([...R.all().js]).toEqual(['R', 'S']); - expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); - expect([...S.all().js]).toEqual(['S']); - expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); - - // But they should be connected through their .vertex/.self: - expect(B.dereference.is_none()).toBe(false); - expect(B.dereference.type).toBe(RayType.VERTEX); - expect(B.dereference.self).not.toBe(B.self); - expect(B.dereference.self.any.js).toBe('B'); - expect(B.dereference.any.js).toBe('___as_vertex'); - expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(1); - expect([...B.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); - - expect(Y.dereference.is_none()).toBe(false); - expect(Y.dereference.type).toBe(RayType.VERTEX); - expect(Y.dereference.self).not.toBe(Y.self); - expect(Y.dereference.self.any.js).toBe('Y'); - expect(Y.dereference.any.js).toBe('___as_vertex'); - expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'B']); - expect([...Y.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'J', 'R']); - - expect(J.dereference.is_none()).toBe(false); - expect(J.dereference.type).toBe(RayType.VERTEX); - expect(J.dereference.self).not.toBe(J.self); - expect(J.dereference.self.any.js).toBe('J'); - expect(J.dereference.any.js).toBe('___as_vertex'); - expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'Y', 'B']); - expect([...J.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'R']); - - expect(R.dereference.is_none()).toBe(false); - expect(R.dereference.type).toBe(RayType.VERTEX); - expect(R.dereference.self).not.toBe(R.self); - expect(R.dereference.self.any.js).toBe('R'); - expect(R.dereference.any.js).toBe('___as_vertex'); - expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); - expect([...R.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['R']); - }); - test("(A:terminal.# = B:initial.#) ; A.as_terminal", () => { - const A_terminal = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }).follow(); - const B_initial = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }).follow(Ray.directions.previous); - - /** - * A ____________ B - * [--|--][--| ][ |--][--|--] - */ - A_terminal.equivalent(B_initial); - - /** - * | - * [ |--][--B--] - * | - * [--A--][--| ] <--- ret - * | - */ - const ret = A_terminal.as_terminal(); - expect(ret.type).toBe(RayType.TERMINAL); - - expect([...A_terminal.dereference.all().js]).toEqual(['___as_vertex', '___as_vertex']); - expect([...A_terminal.dereference.___map(ref => ref.self.follow_direction().any.js)]).toEqual(['A', 'B']); - }); - test("(A:terminal.# = B:initial.# = C:initial.#) ; A.as_terminal", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const A_terminal = A.follow(); - const B_initial = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }).follow(Ray.directions.previous); - const C_initial = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }).follow(Ray.directions.previous); - const D_initial = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }).follow(Ray.directions.previous); - - /** - * A ____________ B - * [--|--][--| ][ |--][--|--] - */ - A_terminal.equivalent(B_initial); - - expect([...A_terminal.dereference.all().js]).toEqual(['B']); - expect([...A_terminal.dereference.___map(ref => ref.any.js)]).toEqual(['B']); - - expect([...B_initial.dereference.all(Ray.directions.previous).js]).toEqual(['A']); - expect([...B_initial.dereference.___map(ref => ref.any.js, { step: Ray.directions.previous})]).toEqual(['A']); - - /** - * | - * [--A--][--| ] - * | - * [ |--][--B--] - * | - * [ |--][--C--] - * | - */ - A_terminal.equivalent(C_initial); - - expect([...A_terminal.dereference.all().js]).toEqual(['___as_vertex', '___as_vertex', '___as_vertex']); - expect([...A_terminal.dereference.___map(ref => ref.self.follow_direction().any.js)]).toEqual(['A', 'B', 'C']); - - /** - * | - * [--A--][--| ] - * | - * [ |--][--B--] - * | - * [ |--][--C--] - * | - * [ |--][--D--] - * | - */ - A_terminal.equivalent(D_initial); - - expect([...A_terminal.dereference.all().js]).toEqual(['___as_vertex', '___as_vertex', '___as_vertex', '___as_vertex']); - expect([...A_terminal.dereference.___map(ref => ref.self.follow_direction().any.js)]).toEqual(['A', 'B', 'C', 'D']); - expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D']); - }); - // test("(A:vertex.# = B:vertex.#) ; B.as_terminal", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // - // A.equivalent(B); - // - // const terminal = B.as_terminal(); - // - // expect(terminal.type).toBe(RayType.TERMINAL); - // - // expect([...terminal.follow(Ray.directions.previous).all(Ray.directions.previous).js]).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - // - // /** - // * These should keep looping... - // * TODO: Better test helper for this - // */ - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); - // }); - // test("(A:vertex.# = B:vertex.#) ; A.as_initial", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // - // A.equivalent(B); - // - // const initial = A.as_initial(); - // - // expect(initial.type).toBe(RayType.INITIAL); - // - // expect([...initial.follow().all(Ray.directions.next).js]).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); - // - // /** - // * These should keep looping... - // * TODO: Better test helper for this - // */ - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); - // }); - // test("(A:vertex.# = B:vertex.#) ; B.as_initial", () => { - // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // - // A.equivalent(B); - // - // const initial = B.as_initial(); - // - // expect(initial.type).toBe(RayType.INITIAL); - // - // expect([...initial.follow().all(Ray.directions.next).js]).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - // - // /** - // * These should keep looping... - // * TODO: Better test helper for this - // */ - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); - // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); - // }); - test("A.equiv(B).equiv(C)", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - A.equivalent(B).equivalent(C); - - expect(A.type).toBe(RayType.VERTEX); - expect(A.self.type).toBe(RayType.VERTEX); - - expect(A.is_none()).toBe(false); - expect(A.any.js).toBe('A'); - expect(A.self.any.js).toBe('___as_vertex'); - expect(A.self.self.any.js).toBe('A'); - expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - - expect(B.type).toBe(RayType.VERTEX); - expect(B.self.type).toBe(RayType.VERTEX); - expect(B.is_none()).toBe(false); - expect(B.any.js).toBe('B'); - expect(B.self.any.js).toBe('___as_vertex'); - expect(B.self.self.any.js).toBe('B'); - expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); - expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - - expect(C.type).toBe(RayType.VERTEX); - expect(C.self.type).toBe(RayType.VERTEX); - expect(C.is_none()).toBe(false); - expect(C.any.js).toBe('C'); - expect(C.self.any.js).toBe('___as_vertex'); - expect(C.self.self.any.js).toBe('C'); - expect([...C.self.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); - expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - }); - test("A.equiv(B).equiv(C).equiv(D).equiv(E).equiv(F) ; different order", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); - const F = Ray.vertex().o({ js: 'F' }).as_reference().o({ js: 'F.#' }); - - A.equivalent(B).equivalent(C).equivalent(D); - D.equivalent(E).equivalent(F); - - - expect(A.type).toBe(RayType.VERTEX); - expect(A.self.type).toBe(RayType.VERTEX); - expect(A.is_none()).toBe(false); - expect(A.any.js).toBe('A'); - expect(A.self.any.js).toBe('___as_vertex'); - expect(A.self.self.any.js).toBe('A'); - expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); - expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - - expect(B.type).toBe(RayType.VERTEX); - expect(B.self.type).toBe(RayType.VERTEX); - expect(B.is_none()).toBe(false); - expect(B.any.js).toBe('B'); - expect(B.self.any.js).toBe('___as_vertex'); - expect(B.self.self.any.js).toBe('B'); - expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); - expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - - expect(C.type).toBe(RayType.VERTEX); - expect(C.self.type).toBe(RayType.VERTEX); - expect(C.is_none()).toBe(false); - expect(C.any.js).toBe('C'); - expect(C.self.any.js).toBe('___as_vertex'); - expect(C.self.self.any.js).toBe('C'); - expect([...C.self.traverse()].map(ref => ref.self.any.js)).toEqual(['C', 'D', 'E', 'F']); - expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect(D.type).toBe(RayType.VERTEX); - expect(D.self.type).toBe(RayType.VERTEX); - expect(D.is_none()).toBe(false); - expect(D.any.js).toBe('D'); - expect(D.self.any.js).toBe('___as_vertex'); - expect(D.self.self.any.js).toBe('D'); - expect([...D.self.traverse()].map(ref => ref.self.any.js)).toEqual(['D', 'E', 'F']); - expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['D', 'C', 'B', 'A']); - - expect(E.type).toBe(RayType.VERTEX); - expect(E.self.type).toBe(RayType.VERTEX); - expect(E.is_none()).toBe(false); - expect(E.any.js).toBe('E'); - expect(E.self.any.js).toBe('___as_vertex'); - expect(E.self.self.any.js).toBe('E'); - expect([...E.self.traverse()].map(ref => ref.self.any.js)).toEqual(['E', 'F']); - expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); - - expect(F.type).toBe(RayType.VERTEX); - expect(F.self.type).toBe(RayType.VERTEX); - expect(F.is_none()).toBe(false); - expect(F.any.js).toBe('F'); - expect(F.self.any.js).toBe('___as_vertex'); - expect(F.self.self.any.js).toBe('F'); - expect([...F.self.traverse()].map(ref => ref.self.any.js)).toEqual(['F']); - expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); - }); - test("A.equiv(B).equiv(C).equiv(D).equiv(E).equiv(F)", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); - const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); - const F = Ray.vertex().o({ js: 'F' }).as_reference().o({ js: 'F.#' }); - - /** - * | - * [--A--] - * | - * [--B--] - * | - * [--C--] - * | - * [--D--] - * | - * [--E--] - * | - * [--F--] - * | - */ - A.equivalent(B).equivalent(C).equivalent(D).equivalent(E).equivalent(F); - - expect(A.type).toBe(RayType.VERTEX); - expect(A.self.type).toBe(RayType.VERTEX); - - expect(A.is_none()).toBe(false); - expect(A.any.js).toBe('A'); - expect(A.self.any.js).toBe('___as_vertex'); - expect(A.self.self.any.js).toBe('A'); - expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); - expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); - - expect(B.type).toBe(RayType.VERTEX); - expect(B.self.type).toBe(RayType.VERTEX); - expect(B.is_none()).toBe(false); - expect(B.any.js).toBe('B'); - expect(B.self.any.js).toBe('___as_vertex'); - expect(B.self.self.any.js).toBe('B'); - expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); - expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); - - expect(C.type).toBe(RayType.VERTEX); - expect(C.self.type).toBe(RayType.VERTEX); - expect(C.is_none()).toBe(false); - expect(C.any.js).toBe('C'); - expect(C.self.any.js).toBe('___as_vertex'); - expect(C.self.self.any.js).toBe('C'); - expect([...C.self.traverse()].map(ref => ref.self.any.js)).toEqual(['C', 'D', 'E', 'F']); - expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); - - expect(D.type).toBe(RayType.VERTEX); - expect(D.self.type).toBe(RayType.VERTEX); - expect(D.is_none()).toBe(false); - expect(D.any.js).toBe('D'); - expect(D.self.any.js).toBe('___as_vertex'); - expect(D.self.self.any.js).toBe('D'); - expect([...D.self.traverse()].map(ref => ref.self.any.js)).toEqual(['D', 'E', 'F']); - expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['D', 'C', 'B', 'A']); - - expect(E.type).toBe(RayType.VERTEX); - expect(E.self.type).toBe(RayType.VERTEX); - expect(E.is_none()).toBe(false); - expect(E.any.js).toBe('E'); - expect(E.self.any.js).toBe('___as_vertex'); - expect(E.self.self.any.js).toBe('E'); - expect([...E.self.traverse()].map(ref => ref.self.any.js)).toEqual(['E', 'F']); - expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); - - expect(F.type).toBe(RayType.VERTEX); - expect(F.self.type).toBe(RayType.VERTEX); - expect(F.is_none()).toBe(false); - expect(F.any.js).toBe('F'); - expect(F.self.any.js).toBe('___as_vertex'); - expect(F.self.self.any.js).toBe('F'); - expect([...F.self.traverse()].map(ref => ref.self.any.js)).toEqual(['F']); - expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); - }); - // test(".None.#.equivalent(.vertex.#)", () => { - // const A = Ray.None().as_reference(); - // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - // - // // const ret = A.equivalent(B); - // - // // expect() - // }); - test("[A, B, C][.as_array, ...]", () => { - const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); - const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); - const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); - - A.compose(B).compose(C); - - expect(A.as_array().map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); - expect(B.as_array().map(ref => ref.any.js)).toEqual(['B', 'C']); - expect(C.as_array().map(ref => ref.any.js)).toEqual(['C']); - - expect([...A].map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); - expect([...A.all().js]).toEqual(['A', 'B', 'C']); - expect([...A.as_generator()].map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); - expect(A.as_string()).toBe('A,B,C'); - - { - - const iterator = A.as_iterator(); - - let array: Ray[] = []; - - while (true) { - let current = iterator.next(); - if (current.done) - break; - - array.push(current.value); - } - - expect(array.map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); - - } - - // TODO async_generator / async_iterator / for await * - }); - test(".next", () => { - let A = Ray.vertex().o({ js: 'A' }).as_reference(); - let B = Ray.vertex().o({ js: 'B'}).as_reference(); - - A.compose(B); - - B = A.next(); - - expect(B.type).toBe(RayType.VERTEX); - expect(B.any.js).toBe('B'); - expect(B.self - .initial.self.initial - .as_reference().any.js - ).toBe('A'); - expect(B.self - .initial.self.initial - .terminal.self.terminal - .as_reference().any.js - ).toBe('B'); - }); - test(".vertex.#.compose(.vertex.#)", () => { - let A = Ray.vertex().o({ js: 'A' }).as_reference(); - let B = Ray.vertex().o({ js: 'B'}).as_reference(); - - B = A.compose(B); - - expect(B.type).toBe(RayType.VERTEX); - expect(B.any.js).toBe('B'); - expect(B.self - .initial.self.initial - .as_reference().any.js - ).toBe('A'); - expect(B.self - .initial.self.initial - .terminal.self.terminal - .as_reference().any.js - ).toBe('B'); - }); - // TODO: .compose(), should take everything at the vertex instead. - // test("[.vertex.#, .vertex.#].#.compose", () => { - // let A = Ray.vertex().o({ js: 'A' }).as_reference(); - // let B = Ray.vertex().o({ js: 'B' }).as_reference(); - // - // B = new Ray({ - // initial: A.as_arbitrary(), - // terminal: B.as_arbitrary() - // }).as_reference().compose(); - // - // expect(B.type).toBe(RayType.VERTEX); - // expect(B.any.js).toBe('B'); - // expect(B.self - // .initial.self.initial - // .as_reference().any.js - // ).toBe('A'); - // expect(B.self - // .initial.self.initial - // .terminal.self.terminal - // .as_reference().any.js - // ).toBe('B'); - // }); - // test(".vertex.#.debug", () => { TODO - // const a = Ray.vertex().as_reference(); - // const b = Ray.vertex().as_reference(); - // a.compose(b); - // - // const debug = {}; - // a.debug(debug); - // - // expect(debug).toEqual('') - // }) - test(".as_arbitrary", () => { - expect(Ray.vertex().o({ js: 'A' }).as_arbitrary()().as_reference().any.js).toBe('A'); - }); - test(".dereference", () => { - const A = Ray.vertex( - Ray.vertex().o({ js: "A.vertex" }).as_arbitrary() - ).o({ js: 'A' }).as_reference(); - - expect(A.dereference.any.js).toBe('A.vertex'); - expect(A.as_reference().dereference.any.js).toBe('A'); - expect(A.as_reference().as_reference().dereference.dereference.any.js).toBe('A'); - expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.any.js).toBe('A'); - expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.dereference.any.js).toBe('A.vertex'); - }); - test(".o", () => { - const ray = Ray.vertex().o({ - a: 'b', - position: [0, 1, 2], - func: () => 'c' - }).as_reference(); - - expect(ray.any.a).toBe('b'); - expect(ray.any.test).toBe(undefined); - expect(() => ray.any.undefinedFunction()).toThrow(); - expect(ray.any.position).toEqual([0, 1, 2]); - expect(ray.any.func()).toBe('c'); - }) - test(".vertex.#", () => { - /** [--|--] */ const vertex = Ray.vertex().as_reference(); - - expect(vertex.type).toBe(RayType.VERTEX); - - expect(vertex.is_none()).toBe(false); - expect(vertex.is_some()).toBe(true); - - expect(vertex.is_initial()).toBe(false); - expect(vertex.is_vertex()).toBe(true); - expect(vertex.is_terminal()).toBe(false); - expect(vertex.is_reference()).toBe(false); - - expect(vertex.self).toBe(vertex.self.initial.terminal); - expect(vertex.self).toBe(vertex.self.terminal.initial); - expect(vertex.self).toBe(vertex.follow(Ray.directions.previous).self.terminal); - }); - test(".vertex.initial.#", () => { - /** [--|--] */ const vertex = Ray.vertex(); - /** [ |--] */ const initial = vertex.initial.as_reference(); - - expect(initial.self.initial.is_none()).toBe(true); - expect(initial.self).not.toBe(initial.self.self); // If self-referential, that means none. - - expect(initial.self.terminal).toBe(vertex); - expect(initial.self.terminal.self).not.toBe(vertex); - expect(initial.self.terminal.initial).toBe(initial.self); - - expect(initial.self.is_none()).toBe(false); - expect(initial.self.self.is_none()).toBe(true); - - expect(initial.is_some()).toBe(true); - expect(initial.self.terminal.is_none()).toBe(false); - - expect(initial.is_initial()).toBe(true); - expect(initial.is_vertex()).toBe(false); - expect(initial.is_terminal()).toBe(false); - expect(initial.is_reference()).toBe(false); - expect(initial.type).toBe(RayType.INITIAL); - }); - test(".initial.#", () => { - /** [ |-?] */ const initial = Ray.initial().as_reference(); - - expect(initial.self.initial.is_none()).toBe(true); - expect(initial.self).not.toBe(initial.self.self); // If self-referential, that means none. - - expect(initial.self).toBe(initial.self.terminal.initial); - expect(initial.self.terminal).toBe(initial.self.terminal.terminal.initial); - - expect(initial.self.terminal.initial).toBe(initial.self); - - expect(initial.self.is_none()).toBe(false); - expect(initial.self.self.is_none()).toBe(true); - - expect(initial.is_some()).toBe(true); - expect(initial.self.terminal.is_none()).toBe(false); - - expect(initial.is_initial()).toBe(true); - expect(initial.is_vertex()).toBe(false); - expect(initial.is_terminal()).toBe(false); - expect(initial.is_reference()).toBe(false); - expect(initial.type).toBe(RayType.INITIAL); - }); - test(".vertex.terminal.#", () => { - /** [--|--] */ const vertex = Ray.vertex(); - /** [ |--] */ const terminal = vertex.terminal.as_reference(); - - expect(terminal.self.terminal.is_none()).toBe(true); - expect(terminal.self).not.toBe(terminal.self.self); // If self-referential, that means none. - - expect(terminal.self.initial).toBe(vertex); - expect(terminal.self.initial.self).not.toBe(vertex); - expect(terminal.self.initial.terminal).toBe(terminal.self); - - expect(terminal.self.is_none()).toBe(false); - expect(terminal.self.self.is_none()).toBe(true); - - expect(terminal.is_some()).toBe(true); - expect(terminal.self.initial.is_none()).toBe(false); - - expect(terminal.is_terminal()).toBe(true); - expect(terminal.is_vertex()).toBe(false); - expect(terminal.is_initial()).toBe(false); - expect(terminal.is_reference()).toBe(false); - expect(terminal.type).toBe(RayType.TERMINAL); - }); - test(".terminal.#", () => { - /** [--| ] */ const terminal = Ray.terminal().as_reference(); - - expect(terminal.self.terminal.is_none()).toBe(true); - expect(terminal.self).not.toBe(terminal.self.self); // If self-referential, that means none. - - expect(terminal.self).toBe(terminal.self.initial.terminal); - expect(terminal.self.initial).toBe(terminal.self.initial.initial.terminal); - - expect(terminal.self.initial.terminal).toBe(terminal.self); - - expect(terminal.self.is_none()).toBe(false); - expect(terminal.self.self.is_none()).toBe(true); - - expect(terminal.is_some()).toBe(true); - expect(terminal.self.initial.is_none()).toBe(false); - - expect(terminal.is_terminal()).toBe(true); - expect(terminal.is_vertex()).toBe(false); - expect(terminal.is_initial()).toBe(false); - expect(terminal.is_reference()).toBe(false); - expect(terminal.type).toBe(RayType.TERMINAL); - }); - test(".None", () => { - /** [ ] */ - const ray = Ray.None(); - - expect(ray.self.is_none()).toBe(true); - expect(ray.self.is_some()).toBe(false); - expect(ray.self.initial.is_none()).toBe(true); - expect(ray.self.vertex.is_none()).toBe(true); - expect(ray.self.terminal.is_none()).toBe(true); - - expect(ray.is_none()).toBe(true); - expect(ray.is_some()).toBe(false); - - expect(ray.is_initial()).toBe(false); - expect(ray.is_vertex()).toBe(true); - expect(ray.is_terminal()).toBe(false); - expect(ray.is_reference()).toBe(false); - expect(ray.type).toBe(RayType.VERTEX); - - }); - test(".None.#", () => { - /** - * [ | ] - * | - * [?????] - */ - - const ray = Ray.None().as_reference(); - - expect(ray.self.is_none()).toBe(true); - expect(ray.self.is_some()).toBe(false); - expect(ray.self.initial.is_none()).toBe(true); - expect(ray.self.vertex.is_none()).toBe(true); - expect(ray.self.terminal.is_none()).toBe(true); - - expect(ray.is_none()).toBe(true); - expect(ray.is_some()).toBe(false); - - expect(ray.is_initial()).toBe(false); - expect(ray.is_vertex()).toBe(true); - expect(ray.is_terminal()).toBe(false); - expect(ray.is_reference()).toBe(false); - expect(ray.type).toBe(RayType.VERTEX); - - }); - test(".None.#.#", () => { - /** - * [ | ] - * | - * [ | ] - * | - * [?????] - */ - const ray = Ray.None().as_reference().as_reference(); - - expect(ray.self.is_none()).toBe(true); - expect(ray.self.is_some()).toBe(false); - - expect(ray.self.initial.is_none()).toBe(true); - expect(ray.self.vertex.is_none()).toBe(true); - expect(ray.self.terminal.is_none()).toBe(true); - - expect(ray.is_none()).toBe(false); - expect(ray.is_some()).toBe(true); - - expect(ray.is_initial()).toBe(true); - expect(ray.is_vertex()).toBe(false); - expect(ray.is_terminal()).toBe(true); - expect(ray.is_reference()).toBe(true); - expect(ray.type).toBe(RayType.REFERENCE); - }); - test(".None.#.#.#", () => { - /** - * ... - * | - * [ | ] - * | - * [ | ] - * | - * [ | ] - * | - * [?????] - */ - let ray = Ray.None().as_reference().as_reference().as_reference(); - - expect(ray.self.is_none()).toBe(false); - expect(ray.self.is_some()).toBe(true); - expect(ray.self.initial.is_none()).toBe(true); - expect(ray.self.vertex.is_none()).toBe(true); - expect(ray.self.terminal.is_none()).toBe(true); - - expect(ray.is_none()).toBe(false); - expect(ray.is_some()).toBe(true); - - expect(ray.is_initial()).toBe(true); - expect(ray.is_vertex()).toBe(false); - expect(ray.is_terminal()).toBe(true); - expect(ray.is_reference()).toBe(true); - expect(ray.type).toBe(RayType.REFERENCE); - }); - test(".None.#.#.#.#[4-15]", () => { - /** - * Basically the empty value is out of scope of our direct drill, and we expect this behavior 'infinitely' up the reference stack. - * ... - * [ | ] <-- ray - * | - * [ | ] <-- ray.self - (ray.self.is_none()) - * | - * [ | ] <-- ray.self.self - (ray.self.self === ray.self.self.self) - * | - * [ | ] <-- ray.self.self.self - = false - * | - * [?????] - */ - for (let i = 4; i <= 15; i++) { - let ray = Ray.None(); - for (let j = 0; j < i; j++) { - ray = ray.as_reference(); - } - - expect(ray.self.is_none()).toBe(false); - expect(ray.self.is_some()).toBe(true); - expect(ray.self.initial.is_none()).toBe(true); - expect(ray.self.vertex.is_none()).toBe(false); - expect(ray.self.terminal.is_none()).toBe(true); - - expect(ray.is_none()).toBe(false); - expect(ray.is_some()).toBe(true); - - expect(ray.is_initial()).toBe(true); - expect(ray.is_vertex()).toBe(false); - expect(ray.is_terminal()).toBe(true); - expect(ray.is_reference()).toBe(true); - expect(ray.type).toBe(RayType.REFERENCE); - } - }); +// test("[A, B, C].copy", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// +// A.compose(B).compose(C); +// +// expect(() => A.copy()).toThrow(); //TODO +// // const copy = A.copy(); +// // expect(A.has_previous()).toBe(false); +// +// // expect(copy.has_previous()).toBe(false); +// }); +// // test("[A, [B, C]]", () => { +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// // +// // /** +// // * [--A--] [--| ] +// // * [ |--] [--B--] +// // */ +// // A.compose(B); +// // +// // /** +// // * [--A--] [--| ] +// // * [ |--] [--B--] +// // * | +// // * [ |--] [--C--] +// // */ +// // A.compose(C); +// // +// // expect(A.follow().type).toEqual(RayType.TERMINAL); +// // expect(A.follow().dereference.type).toEqual(RayType.VERTEX); +// // expect([...A.follow().dereference].map(ref => ref.self.follow_direction().any.js)).toEqual(['A', 'B', 'C']); +// // expect([...A.all().js]).toEqual(['A', 'B', 'C']); +// // // expect([...A].map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); +// // +// // +// // }); +// test(".vertex.#.delete", () => { +// const A_vertex = Ray.vertex().o({ js: 'A' }); +// const A_ref = A_vertex.as_reference().o({ js: 'A.#' }); +// +// expect(A_vertex.is_none()).toBe(false); +// expect(Ray.directions.next(A_ref).is_none()).toBe(false); +// expect(Ray.directions.previous(A_ref).is_none()).toBe(false); +// expect(A_ref.any.js).toBe('A'); +// expect(A_ref.is_none()).toBe(false); +// +// A_ref.delete(); +// +// expect(A_vertex.is_none()).toBe(true); +// expect(Ray.directions.next(A_vertex).is_none()).toBe(true); +// expect(Ray.directions.previous(A_vertex).is_none()).toBe(true); +// expect(A_vertex.any.js).toBe(undefined); +// expect(A_ref.is_none()).toBe(true); +// }); +// test("[A, B, C, D, E].all().js", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); +// const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); +// +// A.compose(B).compose(C).compose(D).compose(E); +// +// expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D', 'E']); +// }); +// test("[A, B, C, D, E].all() ; -= / +=", () => { +// const A = Ray.vertex().o({ js: 'A', value: 0 }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B', value: 1 }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C', value: 2 }).as_reference().o({ js: 'C.#' }); +// const D = Ray.vertex().o({ js: 'D', value: 3 }).as_reference().o({ js: 'D.#' }); +// const E = Ray.vertex().o({ js: 'E', value: 4 }).as_reference().o({ js: 'E.#' }); +// +// A.compose(B).compose(C).compose(D).compose(E); +// +// A.all().value = (value: number) => value - 3; +// expect([...A.all().value]).toEqual([-3, -2, -1, 0, 1]); +// +// C.all().value = (value: number) => value + 10; +// expect([...A.all().value]).toEqual([-3, -2, 9, 10, 11]); +// +// D.all(Ray.directions.previous).value = (value: number) => value - 50; +// expect([...A.all().value]).toEqual([-53, -52, -41, -40, 11]); +// }); +// test("[A, B, C, D, E].___next()", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); +// const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); +// +// A.compose(B).compose(C).compose(D).compose(E); +// +// expect([...A.___next()].map(ref => ref.any.js)).toEqual(['A', 'B', 'C', 'D', 'E']); +// expect(A.last().any.js).toEqual('E'); +// expect(D.first().any.js).toEqual('A'); +// }); +// test("[A, B, C, D, E].traverse()", () => { +// const A = Ray.vertex().o2({ initial: { js: 'A.<<' }, vertex: { js: 'A' }, +// terminal: { js: 'A.>>' } }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o2({ initial: { js: 'B.<<' }, vertex: { js: 'B' }, +// terminal: { js: 'B.>>' } }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o2({ initial: { js: 'C.<<' }, vertex: { js: 'C' }, +// terminal: { js: 'C.>>' } }).as_reference().o({ js: 'C.#' }); +// const D = Ray.vertex().o2({ initial: { js: 'D.<<' }, vertex: { js: 'D' }, +// terminal: { js: 'D.>>' } }).as_reference().o({ js: 'D.#' }); +// const E = Ray.vertex().o2({ initial: { js: 'E.<<' }, vertex: { js: 'E' }, +// terminal: { js: 'E.>>' } }).as_reference().o({ js: 'E.#' }); +// +// A.compose(B).compose(C).compose(D).compose(E); +// +// const branch = Ray.step_function(Ray.directions.next); +// +// let step: Ray = branch.as_ray(A); +// +// expect([step.previous(), step].map(ray => +// [ray.dereference.is_some(), ray.dereference.type, ray.dereference.any.js]) +// ).toEqual( +// [[false, RayType.VERTEX, undefined], [true, RayType.VERTEX, 'A']] +// ); +// +// expect(step.previous().is_none()).toBe(true) +// +// step = step.next(); +// +// expect([step.previous(), step].map(ray => +// [ray.dereference.is_some(), ray.dereference.type, ray.dereference.any.js]) +// ).toEqual( +// [[true, RayType.VERTEX, 'A'], [true, RayType.TERMINAL, 'A.>>']] +// ); +// +// step = step.next(); +// +// expect([step.previous(), step].map(ray => +// [ray.dereference.is_some(), ray.dereference.type, ray.dereference.any.js]) +// ).toEqual( +// [[true, RayType.TERMINAL, 'A.>>'], [true, RayType.INITIAL, 'B.<<']] +// ); +// +// step = step.next(); +// +// expect([step.previous(), step].map(ray => +// [ray.dereference.is_some(), ray.dereference.type, ray.dereference.any.js]) +// ).toEqual( +// [[true, RayType.INITIAL, 'B.<<'], [true, RayType.VERTEX, 'B']] +// ); +// +// }); +// // test("[A, B, C, D, E].___traverse()", () => { +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// // const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); +// // const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); +// // +// // A.compose(B).compose(C).compose(D).compose(E); +// // +// // expect([...A.___traverse()].map(pointer => +// // [pointer.terminal.is_none(), pointer.initial.type, pointer.terminal.type, pointer.initial.any.js] +// // )).toEqual([ +// // [false, RayType.VERTEX, RayType.TERMINAL, 'A'], +// // [false, RayType.TERMINAL, RayType.INITIAL, undefined], +// // [false, RayType.INITIAL, RayType.VERTEX, undefined], +// // [false, RayType.VERTEX, RayType.TERMINAL, 'B'], +// // [false, RayType.TERMINAL, RayType.INITIAL, undefined], +// // [false, RayType.INITIAL, RayType.VERTEX, undefined], +// // [false, RayType.VERTEX, RayType.TERMINAL, 'C'], +// // [false, RayType.TERMINAL, RayType.INITIAL, undefined], +// // [false, RayType.INITIAL, RayType.VERTEX, undefined], +// // [false, RayType.VERTEX, RayType.TERMINAL, 'D'], +// // [false, RayType.TERMINAL, RayType.INITIAL, undefined], +// // [false, RayType.INITIAL, RayType.VERTEX, undefined], +// // [false, RayType.VERTEX, RayType.TERMINAL, 'E'], +// // [true, RayType.TERMINAL, RayType.VERTEX, undefined], // vertex is Ray.None +// // ]); +// // }); +// // test("[A, [B, C, D]].___traverse()", () => { +// // // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// // // +// // // A.compose(B); +// // // A.compose(C); +// // +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const A_terminal = A.follow(); +// // const B_initial = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }).follow(Ray.directions.previous); +// // const C_initial = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }).follow(Ray.directions.previous); +// // const D_initial = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }).follow(Ray.directions.previous); +// // +// // A_terminal.equivalent(B_initial); +// // A_terminal.equivalent(C_initial); +// // A_terminal.equivalent(D_initial); +// // +// // expect([...A.___traverse()].map(pointer => +// // [pointer.terminal.is_none(), pointer.initial.type, pointer.terminal.type, pointer.terminal.is_boundary() ? pointer.terminal.follow_direction().any.js : undefined] +// // )).toEqual([ +// // [false, RayType.VERTEX, RayType.TERMINAL, 'A'], +// // [false, RayType.TERMINAL, RayType.VERTEX, undefined], +// // // [true, RayType.VERTEX, RayType.VERTEX, undefined], +// // ]); +// // }); +// // test("[A, B, C].next()", () => { +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// // +// // A.compose(B).compose(C); +// // +// // // let pointer = A.step(Ray.directions.next()(A)); +// // +// // let pointer = new Ray({ +// // initial: () => A, +// // terminal: () => Ray.directions.next(A), +// // }); +// // +// // /** +// // * ____________ +// // * [ |--] [--| ][ |--] [--| ][ |--] [--| ] +// // * [--A--] [--B--] [--C--] +// // */ +// // +// // expect(pointer.initial.any.js).toBe('A'); +// // +// // expect(pointer.initial.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.type).toBe(RayType.TERMINAL); +// // +// // pointer = pointer.step(); +// // +// // /** +// // * ______________ +// // * [ |--] [--| ][ |--] [--| ][ |--] [--| ] +// // * [--A--] [--B--] [--C--] +// // */ +// // expect(pointer.initial.type).toBe(RayType.TERMINAL); +// // expect(pointer.terminal.type).toBe(RayType.INITIAL); +// // +// // pointer = pointer.step(); +// // +// // /** +// // * ____________ +// // * [ |--] [--| ][ |--] [--| ][ |--] [--| ] +// // * [--A--] [--B--] [--C--] +// // */ +// // expect(pointer.initial.type).toBe(RayType.INITIAL); +// // expect(pointer.terminal.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.any.js).toBe('B'); +// // +// // pointer = pointer.step(); +// // +// // /** +// // * ____________ +// // * [ |--] [--| ][ |--] [--| ][ |--] [--| ] +// // * [--A--] [--B--] [--C--] +// // */ +// // expect(pointer.initial.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.type).toBe(RayType.TERMINAL); +// // +// // pointer = pointer.step(); +// // +// // /** +// // * ______________ +// // * [ |--] [--| ][ |--] [--| ][ |--] [--| ] +// // * [--A--] [--B--] [--C--] +// // */ +// // expect(pointer.initial.type).toBe(RayType.TERMINAL); +// // expect(pointer.terminal.type).toBe(RayType.INITIAL); +// // +// // pointer = pointer.step(); +// // +// // /** +// // * ____________ +// // * [ |--] [--| ][ |--] [--| ][ |--] [--| ] +// // * [--A--] [--B--] [--C--] +// // */ +// // expect(pointer.initial.type).toBe(RayType.INITIAL); +// // expect(pointer.terminal.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.any.js).toBe('C'); +// // +// // pointer = pointer.step(); +// // +// // /** +// // * ____________ +// // * [ |--] [--| ][ |--] [--| ][ |--] [--| ] +// // * [--A--] [--B--] [--C--] +// // */ +// // expect(pointer.initial.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.type).toBe(RayType.TERMINAL); +// // +// // pointer = pointer.step(); +// // +// // /** +// // * _______ +// // * [ |--] [--| ][ |--] [--| ][ |--] [--| ] +// // * [--A--] [--B--] [--C--] +// // */ +// // expect(pointer.initial.type).toBe(RayType.TERMINAL); +// // // expect(pointer.terminal.type).toBe(RayType.TERMINAL); ?? +// // expect(pointer.terminal.is_none()).toBe(true); +// // }); +// // test("[A, B, C].previous()", () => { +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// // +// // A.compose(B).compose(C); +// // +// // // let pointer = A.step(Ray.directions.next()(A)); +// // +// // let pointer = new Ray({ +// // initial: () => C, +// // terminal: () => Ray.directions.previous(C), +// // }); +// // +// // expect(pointer.initial.any.js).toBe('C'); +// // +// // expect(pointer.initial.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.type).toBe(RayType.INITIAL); +// // +// // pointer = pointer.step(); +// // +// // expect(pointer.initial.type).toBe(RayType.INITIAL); +// // expect(pointer.terminal.type).toBe(RayType.TERMINAL); +// // +// // pointer = pointer.step(); +// // +// // expect(pointer.initial.type).toBe(RayType.TERMINAL); +// // expect(pointer.terminal.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.any.js).toBe('B'); +// // +// // pointer = pointer.step(); +// // +// // expect(pointer.initial.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.type).toBe(RayType.INITIAL); +// // +// // pointer = pointer.step(); +// // +// // expect(pointer.initial.type).toBe(RayType.INITIAL); +// // expect(pointer.terminal.type).toBe(RayType.TERMINAL); +// // +// // pointer = pointer.step(); +// // +// // expect(pointer.initial.type).toBe(RayType.TERMINAL); +// // expect(pointer.terminal.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.any.js).toBe('A'); +// // +// // pointer = pointer.step(); +// // +// // expect(pointer.initial.type).toBe(RayType.VERTEX); +// // expect(pointer.terminal.type).toBe(RayType.INITIAL); +// // +// // pointer = pointer.step(); +// // +// // expect(pointer.initial.type).toBe(RayType.INITIAL); +// // // expect(pointer.terminal.type).toBe(RayType.TERMINAL); ?? +// // expect(pointer.terminal.is_none()).toBe(true); +// // }); +// test("[A, B, C][.has_next(), .has_previous()]", () => { +// const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); +// const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); +// const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); +// +// A.compose(B).compose(C); +// +// expect(A.has_next()).toBe(true); +// expect(A.has_next(Ray.directions.next)).toBe(true); +// expect(A.has_next(Ray.directions.previous)).toBe(false); +// expect(A.has_previous()).toBe(false); +// expect(A.has_previous(Ray.directions.previous)).toBe(false); +// expect(A.has_previous(Ray.directions.next)).toBe(true); +// +// expect(B.has_next()).toBe(true); +// expect(B.has_next(Ray.directions.next)).toBe(true); +// expect(B.has_next(Ray.directions.previous)).toBe(true); +// expect(B.has_previous()).toBe(true); +// expect(B.has_previous(Ray.directions.previous)).toBe(true); +// expect(B.has_previous(Ray.directions.next)).toBe(true); +// +// expect(C.has_next()).toBe(false); +// expect(C.has_next(Ray.directions.next)).toBe(false); +// expect(C.has_next(Ray.directions.previous)).toBe(true); +// expect(C.has_previous()).toBe(true); +// expect(C.has_previous(Ray.directions.previous)).toBe(true); +// expect(C.has_previous(Ray.directions.next)).toBe(false); +// }); +// test("[A, B, C][.last(), .first()]", () => { +// const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); +// const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); +// const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); +// +// A.compose(B).compose(C); +// +// expect(A.first().any.js).toBe('A'); +// expect(B.first().any.js).toBe('A'); +// expect(C.first().any.js).toBe('A'); +// +// expect(A.last().any.js).toBe('C'); +// expect(B.last().any.js).toBe('C'); +// expect(C.last().any.js).toBe('C'); +// }); +// test("[A, B, C][.at()]", () => { +// const A = Ray.vertex().o({js: 'A'}).as_reference().o({js: 'A.#'}); +// const B = Ray.vertex().o({js: 'B'}).as_reference().o({js: 'B.#'}); +// const C = Ray.vertex().o({js: 'C'}).as_reference().o({js: 'C.#'}); +// +// A.compose(B).compose(C); +// +// expect(A.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); +// expect(A.at(-100).is_none()).toBe(true); +// expect(A.at(-1).is_none()).toBe(true); +// expect(A.at(0).any.js).toBe('A'); +// expect(A.at(1).any.js).toBe('B'); +// expect(A.at(2).any.js).toBe('C'); +// expect(A.at(3).is_none()).toBe(true); +// expect(A.at(100).is_none()).toBe(true); +// expect(A.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); +// +// expect(B.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); +// expect(B.at(-100).is_none()).toBe(true); +// expect(B.at(-2).is_none()).toBe(true); +// expect(B.at(-1).any.js).toBe('A'); +// expect(B.at(0).any.js).toBe('B'); +// expect(B.at(1).any.js).toBe('C'); +// expect(B.at(2).is_none()).toBe(true); +// expect(B.at(100).is_none()).toBe(true); +// expect(B.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); +// +// expect(C.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); +// expect(C.at(-100).is_none()).toBe(true); +// expect(C.at(-3).is_none()).toBe(true); +// expect(C.at(-2).any.js).toBe('A'); +// expect(C.at(-1).any.js).toBe('B'); +// expect(C.at(0).any.js).toBe('C'); +// expect(C.at(1).is_none()).toBe(true); +// expect(C.at(100).is_none()).toBe(true); +// expect(C.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); +// }); +// test(".permutation", () => { +// const A = Ray.permutation(0, 3); +// const B = Ray.permutation(1, 3); +// const C = Ray.permutation(2, 3); +// +// expect(A.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); +// expect(A.at(-100).is_none()).toBe(true); +// expect(A.at(-1).is_none()).toBe(true); +// +// expect(A.at(0).is_some()).toBe(true); +// expect(A.at(1).is_some()).toBe(true); +// expect(A.at(2).is_some()).toBe(true); +// +// expect(A.at(3).is_none()).toBe(true); +// expect(A.at(100).is_none()).toBe(true); +// expect(A.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); +// +// +// expect(B.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); +// expect(B.at(-100).is_none()).toBe(true); +// expect(B.at(-2).is_none()).toBe(true); +// +// expect(B.at(-1).is_some()).toBe(true); +// expect(B.at(0).is_some()).toBe(true); +// expect(B.at(1).is_some()).toBe(true); +// +// expect(B.at(2).is_none()).toBe(true); +// expect(B.at(100).is_none()).toBe(true); +// expect(B.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); +// +// +// expect(C.at(Number.MIN_VALUE.valueOf()).is_none()).toBe(true); +// expect(C.at(-100).is_none()).toBe(true); +// expect(C.at(-3).is_none()).toBe(true); +// +// expect(C.at(-2).is_some()).toBe(true); +// expect(C.at(-1).is_some()).toBe(true); +// expect(C.at(0).is_some()).toBe(true); +// +// expect(C.at(1).is_none()).toBe(true); +// expect(C.at(100).is_none()).toBe(true); +// expect(C.at(Number.MAX_VALUE.valueOf()).is_none()).toBe(true); +// }); +// test("[A, B, C][.next(), .previous()]", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// +// expect(A.next().is_none()).toBe(true); +// expect(A.previous().is_none()).toBe(true); +// +// A.compose(B).compose(C); +// +// expect(A.next().is_none()).toBe(false); +// expect(A.previous().is_none()).toBe(true); +// +// expect(A.next().next().next().is_none()).toBe(true); +// +// expect(A.next().type).toBe(RayType.VERTEX); +// // expect(current.next().any.js).toBe('B.#'); TODO, maybe the ref?? +// expect(A.next().any.js).toBe('B'); +// +// expect(A.next().next().type).toBe(RayType.VERTEX); +// expect(A.next().next().any.js).toBe('C'); +// +// expect(A.next().previous().any.js).toBe('A'); +// expect(A.next().next().previous().any.js).toBe('B'); +// expect(A.next().next().previous().previous().any.js).toBe('A'); +// expect(A.next().previous().next().next().previous().any.js).toBe('B'); +// expect(A.next().previous().next().next().previous().next().any.js).toBe('C'); +// }); +// test("[A, B, C], [X, Y, Z] ; C.compose(X)", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// +// const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); +// const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); +// const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); +// +// A.compose(B).compose(C); +// X.compose(Y).compose(Z); +// +// C.compose(X); +// +// expect([...A.all().js]).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); +// expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); +// expect([...X.all(Ray.directions.previous).js]).toEqual(['X', 'C', 'B', 'A']); +// expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); +// }); +// // test("[A, B, C], [X, Y, Z] ; B.compose(X)", () => { +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// // +// // const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); +// // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); +// // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); +// // +// // A.compose(B).compose(C); +// // X.compose(Y).compose(Z); +// // +// // B.compose(X); +// // +// // // expect([...A.all().js]).toEqual(['A', 'B', 'C', 'X', 'Y', 'Z']); +// // // expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X', 'C', 'B', 'A']); +// // // expect([...X.all(Ray.directions.previous).js]).toEqual(['X', 'C', 'B', 'A']); +// // // expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); +// // }); +// test("[A, [X, Y, Z].initial, B, C][.next(), .previous()]", () => { +// // /** +// // * | | +// // * |-- A --| |-- B --|-- C --| +// // * | \ | +// // * |-- X --| +// // * | \ | +// // * |-- Y --| +// // * | \ | +// // * |-- Z --| +// // * | \ | (Destroys the '\' connections) TODO: This should be optional/more complexly constructed +// // */ +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// // +// // const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); +// // const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); +// // const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); +// // +// // X.compose(Y).compose(Z); +// // +// // const ret = A.compose(X.follow(Ray.directions.previous)); +// +// +// +// // /** +// // * | +// // * |-- A --| +// // * | \ <-- '\' is 'ret' +// // * |-- X --| +// // * | \ +// // * |-- Y --| +// // * | \ +// // * |-- Z --| +// // * | \ +// // */ +// // expect(ret.type).toBe(RayType.INITIAL); +// // expect(ret.follow().is_none()).toBe(false); +// // expect([...ret.follow()].map( +// // return_ref => return_ref.type +// // )).toEqual([RayType.VERTEX, RayType.VERTEX, RayType.VERTEX]); +// // expect([...ret.follow()].map( +// // return_ref => return_ref.self.type +// // )).toEqual([RayType.TERMINAL, RayType.TERMINAL, RayType.TERMINAL]); +// // expect([...ret.follow()].map( +// // return_ref => { +// // const return_vertex = return_ref.self; +// // const terminal = return_vertex.self; +// // const continued_vertex = terminal.initial; +// // +// // return continued_vertex.any.js; +// // } +// // )).toEqual(['X', 'Y', 'Z']); +// // expect([...ret.follow()].map( +// // return_ref => { +// // const vertex = return_ref.self; +// // const terminal = vertex.self; +// // +// // return terminal.self.as_reference().is_none(); +// // } +// // )).toEqual([true, true, true]); // From the perspective of the 'terminal' it's ignorant of 'ret'. +// // +// // expect(A.next().type).toBe(RayType.INITIAL); +// // +// // /** +// // * | | +// // * |-- A --| |-- B --|-- C --| +// // * | | +// // * |-- X --| +// // * | | +// // * |-- Y --| +// // * | | +// // * |-- Z --| +// // * | | +// // */ +// // ret.compose(B).compose(C); +// // +// +// }); +// // test(".None.#.equivalent(.None.#)", () => { +// // const A = Ray.None().o({ js: 'A' }).as_reference(); // TODO Tagging the 'NONE' vertices here is incredibly inconsistent, but just to demonstrate the test. +// // const B = Ray.None().o({ js: 'B' }).as_reference(); +// // +// // expect(A.type).toBe(RayType.VERTEX); +// // expect(B.type).toBe(RayType.VERTEX); +// // +// // expect(A.is_none()).toBe(true); +// // expect(A.any.js).toBe('A'); +// // expect(A.self.any.js).toBe('A'); +// // expect(A.self.self.any.js).toBe('A'); +// // +// // expect(B.is_none()).toBe(true); +// // expect(B.any.js).toBe('B'); +// // expect(B.self.any.js).toBe('B'); +// // expect(B.self.self.any.js).toBe('B'); +// // +// // A.equivalent(B); +// // +// // expect(A.type).toBe(RayType.REFERENCE); // Turns A into a reference to B. +// // expect(B.type).toBe(RayType.REFERENCE); // Turns B into a reference to A. +// // +// // expect(A.is_none()).toBe(false); +// // expect(A.any.js).toBe('A'); +// // expect(A.self.any.js).toBe('B'); +// // expect(A.self.self.any.js).toBe('A'); +// // +// // expect(B.is_none()).toBe(false); +// // expect(B.any.js).toBe('B'); +// // expect(B.self.any.js).toBe('A'); +// // expect(B.self.self.any.js).toBe('B'); +// // }); +// test(".vertex.#.equivalent(.vertex.#)", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// +// expect(A.type).toBe(RayType.VERTEX); +// expect(B.type).toBe(RayType.VERTEX); +// expect(A.as_reference().any.js).toBe('A.#'); +// expect(B.as_reference().any.js).toBe('B.#'); +// +// expect(A.is_none()).toBe(false); +// expect(A.dereference.is_none()).toBe(true); +// +// expect(B.is_none()).toBe(false); +// expect(B.dereference.is_none()).toBe(true); +// +// A.equivalent(B); +// +// expect(A.type).toBe(RayType.VERTEX); +// expect(A.self.type).toBe(RayType.VERTEX); +// expect(A.is_none()).toBe(false); +// expect(A.any.js).toBe('A'); +// expect(A.self.any.js).toBe('___as_vertex'); +// expect(A.self.self.any.js).toBe('A'); +// expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B']); +// expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); +// +// expect(B.type).toBe(RayType.VERTEX); +// expect(B.self.type).toBe(RayType.VERTEX); +// expect(B.is_none()).toBe(false); +// expect(B.any.js).toBe('B'); +// expect(B.self.any.js).toBe('___as_vertex'); +// expect(B.self.self.any.js).toBe('B'); +// expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B']); +// expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); +// }); +// test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y).equiv(J).equiv(R)", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// +// const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); +// const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); +// const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); +// +// const I = Ray.vertex().o({ js: 'I' }).as_reference().o({ js: 'I.#' }); +// const J = Ray.vertex().o({ js: 'J' }).as_reference().o({ js: 'J.#' }); +// const K = Ray.vertex().o({ js: 'K' }).as_reference().o({ js: 'K.#' }); +// +// const Q = Ray.vertex().o({ js: 'Q' }).as_reference().o({ js: 'Q.#' }); +// const R = Ray.vertex().o({ js: 'R' }).as_reference().o({ js: 'R.#' }); +// const S = Ray.vertex().o({ js: 'S' }).as_reference().o({ js: 'S.#' }); +// +// A.compose(B).compose(C); +// X.compose(Y).compose(Z); +// I.compose(J).compose(K); +// Q.compose(R).compose(S); +// +// // BEFORE .equivalent +// expect([...A.all().js]).toEqual(['A', 'B', 'C']); +// expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); +// expect([...B.all().js]).toEqual(['B', 'C']); +// expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); +// expect([...C.all().js]).toEqual(['C']); +// expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); +// +// expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); +// expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); +// expect([...Y.all().js]).toEqual(['Y', 'Z']); +// expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); +// expect([...Z.all().js]).toEqual(['Z']); +// expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); +// +// expect([...I.all().js]).toEqual(['I', 'J', 'K']); +// expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); +// expect([...J.all().js]).toEqual(['J', 'K']); +// expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); +// expect([...K.all().js]).toEqual(['K']); +// expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); +// +// expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); +// expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); +// expect([...R.all().js]).toEqual(['R', 'S']); +// expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); +// expect([...S.all().js]).toEqual(['S']); +// expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); +// +// /** +// * Drawing an equivalence between `B -> Y -> J -> R`. (Doesn't need to hold in some more abstract sense, it's just a line) +// * | +// * [--A--][--B--][--C--] +// * | +// * [--X--][--Y--][--Z--] +// * | +// * [--I--][--J--][--K--] +// * | +// * [--Q--][--R--][--S--] +// * | +// */ +// B.equivalent(Y).equivalent(J).equivalent(R); +// +// // TODO: Bug is from one empty side. +// // TODO: Still one bug, J.# ->, makes the equiv(R) a parallel composition, so something is TERMINAL/INITIAL -> VERTEX +// +// // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) +// expect([...A.all().js]).toEqual(['A', 'B', 'C']); +// expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); +// expect([...B.all().js]).toEqual(['B', 'C']); +// expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); +// expect([...C.all().js]).toEqual(['C']); +// expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); +// +// expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); +// expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); +// expect([...Y.all().js]).toEqual(['Y', 'Z']); +// expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); +// expect([...Z.all().js]).toEqual(['Z']); +// expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); +// +// expect([...I.all().js]).toEqual(['I', 'J', 'K']); +// expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); +// expect([...J.all().js]).toEqual(['J', 'K']); +// expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); +// expect([...K.all().js]).toEqual(['K']); +// expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); +// +// expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); +// expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); +// expect([...R.all().js]).toEqual(['R', 'S']); +// expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); +// expect([...S.all().js]).toEqual(['S']); +// expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); +// +// // But they should be connected through their .vertex/.self: +// expect(B.dereference.is_none()).toBe(false); +// expect(B.dereference.type).toBe(RayType.VERTEX); +// expect(B.dereference.self).not.toBe(B.self); +// expect(B.dereference.self.any.js).toBe('B'); +// expect(B.dereference.any.js).toBe('___as_vertex'); +// expect([...B.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B']); +// expect([...B.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); +// +// expect(Y.dereference.is_none()).toBe(false); +// expect(Y.dereference.type).toBe(RayType.VERTEX); +// expect(Y.dereference.self).not.toBe(Y.self); +// expect(Y.dereference.self.any.js).toBe('Y'); +// expect(Y.dereference.any.js).toBe('___as_vertex'); +// expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'B']); +// expect([...Y.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'J', 'R']); +// +// expect(J.dereference.is_none()).toBe(false); +// expect(J.dereference.type).toBe(RayType.VERTEX); +// expect(J.dereference.self).not.toBe(J.self); +// expect(J.dereference.self.any.js).toBe('J'); +// expect(J.dereference.any.js).toBe('___as_vertex'); +// expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'Y', 'B']); +// expect([...J.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'R']); +// +// expect(R.dereference.is_none()).toBe(false); +// expect(R.dereference.type).toBe(RayType.VERTEX); +// expect(R.dereference.self).not.toBe(R.self); +// expect(R.dereference.self.any.js).toBe('R'); +// expect(R.dereference.any.js).toBe('___as_vertex'); +// expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); +// expect([...R.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['R']); +// }); +// test("([ABC], [XYZ], [IJK]]) ; B.equiv(Y).equiv(J)", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// +// const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); +// const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); +// const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); +// +// const I = Ray.vertex().o({ js: 'I' }).as_reference().o({ js: 'I.#' }); +// const J = Ray.vertex().o({ js: 'J' }).as_reference().o({ js: 'J.#' }); +// const K = Ray.vertex().o({ js: 'K' }).as_reference().o({ js: 'K.#' }); +// +// A.compose(B).compose(C); +// X.compose(Y).compose(Z); +// I.compose(J).compose(K); +// +// // BEFORE .equivalent +// expect([...A.all().js]).toEqual(['A', 'B', 'C']); +// expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); +// expect([...B.all().js]).toEqual(['B', 'C']); +// expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); +// expect([...C.all().js]).toEqual(['C']); +// expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); +// +// expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); +// expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); +// expect([...Y.all().js]).toEqual(['Y', 'Z']); +// expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); +// expect([...Z.all().js]).toEqual(['Z']); +// expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); +// +// expect([...I.all().js]).toEqual(['I', 'J', 'K']); +// expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); +// expect([...J.all().js]).toEqual(['J', 'K']); +// expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); +// expect([...K.all().js]).toEqual(['K']); +// expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); +// +// /** +// * Drawing an equivalence between `B -> Y -> J`. (Doesn't need to hold in some more abstract sense, it's just a line) +// * | +// * [--A--][--B--][--C--] +// * | +// * [--X--][--Y--][--Z--] +// * | +// * [--I--][--J--][--K--] +// * | +// */ +// B.equivalent(Y).equivalent(J); +// +// // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) +// expect([...A.all().js]).toEqual(['A', 'B', 'C']); +// expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); +// expect([...B.all().js]).toEqual(['B', 'C']); +// expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); +// expect([...C.all().js]).toEqual(['C']); +// expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); +// +// expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); +// expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); +// expect([...Y.all().js]).toEqual(['Y', 'Z']); +// expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); +// expect([...Z.all().js]).toEqual(['Z']); +// expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); +// +// expect([...I.all().js]).toEqual(['I', 'J', 'K']); +// expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); +// expect([...J.all().js]).toEqual(['J', 'K']); +// expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); +// expect([...K.all().js]).toEqual(['K']); +// expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); +// +// // But they should be connected through their .vertex/.self: +// expect(B.dereference.is_none()).toBe(false); +// expect(B.dereference.type).toBe(RayType.VERTEX); +// expect(B.dereference.self).not.toBe(B.self); +// expect(B.dereference.self.any.js).toBe('B'); +// expect(B.dereference.any.js).toBe('___as_vertex'); +// expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(1); +// expect([...B.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'Y', 'J']); +// +// expect(Y.dereference.is_none()).toBe(false); +// expect(Y.dereference.type).toBe(RayType.VERTEX); +// expect(Y.dereference.self).not.toBe(Y.self); +// expect(Y.dereference.self.any.js).toBe('Y'); +// expect(Y.dereference.any.js).toBe('___as_vertex'); +// expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'B']); +// expect([...Y.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'J']); +// +// expect(J.dereference.is_none()).toBe(false); +// expect(J.dereference.type).toBe(RayType.VERTEX); +// expect(J.dereference.self).not.toBe(J.self); +// expect(J.dereference.self.any.js).toBe('J'); +// expect(J.dereference.any.js).toBe('___as_vertex'); +// expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'Y', 'B']); +// expect([...J.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['J']); +// }); +// test("([ABC], [XYZ], [IJK], [QRS]) ; B.equiv(Y) ; J.equiv(J) ; Y.equiv(J)", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// +// const X = Ray.vertex().o({ js: 'X' }).as_reference().o({ js: 'X.#' }); +// const Y = Ray.vertex().o({ js: 'Y' }).as_reference().o({ js: 'Y.#' }); +// const Z = Ray.vertex().o({ js: 'Z' }).as_reference().o({ js: 'Z.#' }); +// +// const I = Ray.vertex().o({ js: 'I' }).as_reference().o({ js: 'I.#' }); +// const J = Ray.vertex().o({ js: 'J' }).as_reference().o({ js: 'J.#' }); +// const K = Ray.vertex().o({ js: 'K' }).as_reference().o({ js: 'K.#' }); +// +// const Q = Ray.vertex().o({ js: 'Q' }).as_reference().o({ js: 'Q.#' }); +// const R = Ray.vertex().o({ js: 'R' }).as_reference().o({ js: 'R.#' }); +// const S = Ray.vertex().o({ js: 'S' }).as_reference().o({ js: 'S.#' }); +// +// A.compose(B).compose(C); +// X.compose(Y).compose(Z); +// I.compose(J).compose(K); +// Q.compose(R).compose(S); +// +// // BEFORE .equivalent +// expect([...A.all().js]).toEqual(['A', 'B', 'C']); +// expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); +// expect([...B.all().js]).toEqual(['B', 'C']); +// expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); +// expect([...C.all().js]).toEqual(['C']); +// expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); +// +// expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); +// expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); +// expect([...Y.all().js]).toEqual(['Y', 'Z']); +// expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); +// expect([...Z.all().js]).toEqual(['Z']); +// expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); +// +// expect([...I.all().js]).toEqual(['I', 'J', 'K']); +// expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); +// expect([...J.all().js]).toEqual(['J', 'K']); +// expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); +// expect([...K.all().js]).toEqual(['K']); +// expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); +// +// expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); +// expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); +// expect([...R.all().js]).toEqual(['R', 'S']); +// expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); +// expect([...S.all().js]).toEqual(['S']); +// expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); +// +// /** +// * Drawing an equivalence between `B -> Y -> J -> R`. (Doesn't need to hold in some more abstract sense, it's just a line) +// * | +// * [--A--][--B--][--C--] +// * | +// * [--X--][--Y--][--Z--] +// * | +// * [--I--][--J--][--K--] +// * | +// * [--Q--][--R--][--S--] +// * | +// */ +// B.equivalent(Y); +// J.equivalent(R); +// Y.equivalent(J); +// +// // AFTER .equivalent (Ensure the composed vertices didn't change in their respective directions) +// expect([...A.all().js]).toEqual(['A', 'B', 'C']); +// expect([...A.all(Ray.directions.previous).js]).toEqual(['A']); +// expect([...B.all().js]).toEqual(['B', 'C']); +// expect([...B.all(Ray.directions.previous).js]).toEqual(['B', 'A']); +// expect([...C.all().js]).toEqual(['C']); +// expect([...C.all(Ray.directions.previous).js]).toEqual(['C', 'B', 'A']); +// +// expect([...X.all().js]).toEqual(['X', 'Y', 'Z']); +// expect([...X.all(Ray.directions.previous).js]).toEqual(['X']); +// expect([...Y.all().js]).toEqual(['Y', 'Z']); +// expect([...Y.all(Ray.directions.previous).js]).toEqual(['Y', 'X']); +// expect([...Z.all().js]).toEqual(['Z']); +// expect([...Z.all(Ray.directions.previous).js]).toEqual(['Z', 'Y', 'X']); +// +// expect([...I.all().js]).toEqual(['I', 'J', 'K']); +// expect([...I.all(Ray.directions.previous).js]).toEqual(['I']); +// expect([...J.all().js]).toEqual(['J', 'K']); +// expect([...J.all(Ray.directions.previous).js]).toEqual(['J', 'I']); +// expect([...K.all().js]).toEqual(['K']); +// expect([...K.all(Ray.directions.previous).js]).toEqual(['K', 'J', 'I']); +// +// expect([...Q.all().js]).toEqual(['Q', 'R', 'S']); +// expect([...Q.all(Ray.directions.previous).js]).toEqual(['Q']); +// expect([...R.all().js]).toEqual(['R', 'S']); +// expect([...R.all(Ray.directions.previous).js]).toEqual(['R', 'Q']); +// expect([...S.all().js]).toEqual(['S']); +// expect([...S.all(Ray.directions.previous).js]).toEqual(['S', 'R', 'Q']); +// +// // But they should be connected through their .vertex/.self: +// expect(B.dereference.is_none()).toBe(false); +// expect(B.dereference.type).toBe(RayType.VERTEX); +// expect(B.dereference.self).not.toBe(B.self); +// expect(B.dereference.self.any.js).toBe('B'); +// expect(B.dereference.any.js).toBe('___as_vertex'); +// expect([...B.dereference.traverse(Ray.directions.previous)].length).toBe(1); +// expect([...B.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'Y', 'J', 'R']); +// +// expect(Y.dereference.is_none()).toBe(false); +// expect(Y.dereference.type).toBe(RayType.VERTEX); +// expect(Y.dereference.self).not.toBe(Y.self); +// expect(Y.dereference.self.any.js).toBe('Y'); +// expect(Y.dereference.any.js).toBe('___as_vertex'); +// expect([...Y.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['Y', 'B']); +// expect([...Y.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['Y', 'J', 'R']); +// +// expect(J.dereference.is_none()).toBe(false); +// expect(J.dereference.type).toBe(RayType.VERTEX); +// expect(J.dereference.self).not.toBe(J.self); +// expect(J.dereference.self.any.js).toBe('J'); +// expect(J.dereference.any.js).toBe('___as_vertex'); +// expect([...J.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['J', 'Y', 'B']); +// expect([...J.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['J', 'R']); +// +// expect(R.dereference.is_none()).toBe(false); +// expect(R.dereference.type).toBe(RayType.VERTEX); +// expect(R.dereference.self).not.toBe(R.self); +// expect(R.dereference.self.any.js).toBe('R'); +// expect(R.dereference.any.js).toBe('___as_vertex'); +// expect([...R.dereference.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['R', 'J', 'Y', 'B']); +// expect([...R.dereference.traverse()].map(ref => ref.self.any.js)).toEqual(['R']); +// }); +// // test("(A:terminal.# = B:initial.#) ; A.as_terminal", () => { +// // const A_terminal = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }).follow(); +// // const B_initial = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }).follow(Ray.directions.previous); +// // +// // /** +// // * A ____________ B +// // * [--|--][--| ][ |--][--|--] +// // */ +// // A_terminal.equivalent(B_initial); +// // +// // /** +// // * | +// // * [ |--][--B--] +// // * | +// // * [--A--][--| ] <--- ret +// // * | +// // */ +// // const ret = A_terminal.as_terminal(); +// // expect(ret.type).toBe(RayType.TERMINAL); +// // +// // expect([...A_terminal.dereference.all().js]).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...A_terminal.dereference.___map(ref => ref.self.follow_direction().any.js)]).toEqual(['A', 'B']); +// // }); +// // test("(A:terminal.# = B:initial.# = C:initial.#) ; A.as_terminal", () => { +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const A_terminal = A.follow(); +// // const B_initial = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }).follow(Ray.directions.previous); +// // const C_initial = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }).follow(Ray.directions.previous); +// // const D_initial = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }).follow(Ray.directions.previous); +// // +// // /** +// // * A ____________ B +// // * [--|--][--| ][ |--][--|--] +// // */ +// // A_terminal.equivalent(B_initial); +// // +// // expect([...A_terminal.dereference.all().js]).toEqual(['B']); +// // expect([...A_terminal.dereference.___map(ref => ref.any.js)]).toEqual(['B']); +// // +// // expect([...B_initial.dereference.all(Ray.directions.previous).js]).toEqual(['A']); +// // expect([...B_initial.dereference.___map(ref => ref.any.js, { step: Ray.directions.previous})]).toEqual(['A']); +// // +// // /** +// // * | +// // * [--A--][--| ] +// // * | +// // * [ |--][--B--] +// // * | +// // * [ |--][--C--] +// // * | +// // */ +// // A_terminal.equivalent(C_initial); +// // +// // expect([...A_terminal.dereference.all().js]).toEqual(['___as_vertex', '___as_vertex', '___as_vertex']); +// // expect([...A_terminal.dereference.___map(ref => ref.self.follow_direction().any.js)]).toEqual(['A', 'B', 'C']); +// // +// // /** +// // * | +// // * [--A--][--| ] +// // * | +// // * [ |--][--B--] +// // * | +// // * [ |--][--C--] +// // * | +// // * [ |--][--D--] +// // * | +// // */ +// // A_terminal.equivalent(D_initial); +// // +// // expect([...A_terminal.dereference.all().js]).toEqual(['___as_vertex', '___as_vertex', '___as_vertex', '___as_vertex']); +// // expect([...A_terminal.dereference.___map(ref => ref.self.follow_direction().any.js)]).toEqual(['A', 'B', 'C', 'D']); +// // expect([...A.all().js]).toEqual(['A', 'B', 'C', 'D']); +// // }); +// // test("(A:vertex.# = B:vertex.#) ; B.as_terminal", () => { +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // +// // A.equivalent(B); +// // +// // const terminal = B.as_terminal(); +// // +// // expect(terminal.type).toBe(RayType.TERMINAL); +// // +// // expect([...terminal.follow(Ray.directions.previous).all(Ray.directions.previous).js]).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); +// // +// // /** +// // * These should keep looping... +// // * TODO: Better test helper for this +// // */ +// // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); +// // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...terminal.follow(Ray.directions.previous).traverse(Ray.directions.previous)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); +// // }); +// // test("(A:vertex.# = B:vertex.#) ; A.as_initial", () => { +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // +// // A.equivalent(B); +// // +// // const initial = A.as_initial(); +// // +// // expect(initial.type).toBe(RayType.INITIAL); +// // +// // expect([...initial.follow().all(Ray.directions.next).js]).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['A', 'B']); +// // +// // /** +// // * These should keep looping... +// // * TODO: Better test helper for this +// // */ +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['A', 'B']); +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['A', 'B']); +// // }); +// // test("(A:vertex.# = B:vertex.#) ; B.as_initial", () => { +// // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // +// // A.equivalent(B); +// // +// // const initial = B.as_initial(); +// // +// // expect(initial.type).toBe(RayType.INITIAL); +// // +// // expect([...initial.follow().all(Ray.directions.next).js]).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); +// // +// // /** +// // * These should keep looping... +// // * TODO: Better test helper for this +// // */ +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.any.js)).toEqual(['B', 'A']); +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.any.js)).toEqual(['___as_vertex', '___as_vertex']); +// // expect([...initial.follow().traverse(Ray.directions.next)].map(ref => ref.self.self.self.self.self.any.js)).toEqual(['B', 'A']); +// // }); +// test("A.equiv(B).equiv(C)", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// +// A.equivalent(B).equivalent(C); +// +// expect(A.type).toBe(RayType.VERTEX); +// expect(A.self.type).toBe(RayType.VERTEX); +// +// expect(A.is_none()).toBe(false); +// expect(A.any.js).toBe('A'); +// expect(A.self.any.js).toBe('___as_vertex'); +// expect(A.self.self.any.js).toBe('A'); +// expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C']); +// expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); +// +// expect(B.type).toBe(RayType.VERTEX); +// expect(B.self.type).toBe(RayType.VERTEX); +// expect(B.is_none()).toBe(false); +// expect(B.any.js).toBe('B'); +// expect(B.self.any.js).toBe('___as_vertex'); +// expect(B.self.self.any.js).toBe('B'); +// expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C']); +// expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); +// +// expect(C.type).toBe(RayType.VERTEX); +// expect(C.self.type).toBe(RayType.VERTEX); +// expect(C.is_none()).toBe(false); +// expect(C.any.js).toBe('C'); +// expect(C.self.any.js).toBe('___as_vertex'); +// expect(C.self.self.any.js).toBe('C'); +// expect([...C.self.traverse()].map(ref => ref.self.any.js)).toEqual(['C']); +// expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); +// }); +// test("A.equiv(B).equiv(C).equiv(D).equiv(E).equiv(F) ; different order", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); +// const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); +// const F = Ray.vertex().o({ js: 'F' }).as_reference().o({ js: 'F.#' }); +// +// A.equivalent(B).equivalent(C).equivalent(D); +// D.equivalent(E).equivalent(F); +// +// +// expect(A.type).toBe(RayType.VERTEX); +// expect(A.self.type).toBe(RayType.VERTEX); +// expect(A.is_none()).toBe(false); +// expect(A.any.js).toBe('A'); +// expect(A.self.any.js).toBe('___as_vertex'); +// expect(A.self.self.any.js).toBe('A'); +// expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); +// expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); +// +// expect(B.type).toBe(RayType.VERTEX); +// expect(B.self.type).toBe(RayType.VERTEX); +// expect(B.is_none()).toBe(false); +// expect(B.any.js).toBe('B'); +// expect(B.self.any.js).toBe('___as_vertex'); +// expect(B.self.self.any.js).toBe('B'); +// expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); +// expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); +// +// expect(C.type).toBe(RayType.VERTEX); +// expect(C.self.type).toBe(RayType.VERTEX); +// expect(C.is_none()).toBe(false); +// expect(C.any.js).toBe('C'); +// expect(C.self.any.js).toBe('___as_vertex'); +// expect(C.self.self.any.js).toBe('C'); +// expect([...C.self.traverse()].map(ref => ref.self.any.js)).toEqual(['C', 'D', 'E', 'F']); +// expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); +// +// expect(D.type).toBe(RayType.VERTEX); +// expect(D.self.type).toBe(RayType.VERTEX); +// expect(D.is_none()).toBe(false); +// expect(D.any.js).toBe('D'); +// expect(D.self.any.js).toBe('___as_vertex'); +// expect(D.self.self.any.js).toBe('D'); +// expect([...D.self.traverse()].map(ref => ref.self.any.js)).toEqual(['D', 'E', 'F']); +// expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['D', 'C', 'B', 'A']); +// +// expect(E.type).toBe(RayType.VERTEX); +// expect(E.self.type).toBe(RayType.VERTEX); +// expect(E.is_none()).toBe(false); +// expect(E.any.js).toBe('E'); +// expect(E.self.any.js).toBe('___as_vertex'); +// expect(E.self.self.any.js).toBe('E'); +// expect([...E.self.traverse()].map(ref => ref.self.any.js)).toEqual(['E', 'F']); +// expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); +// +// expect(F.type).toBe(RayType.VERTEX); +// expect(F.self.type).toBe(RayType.VERTEX); +// expect(F.is_none()).toBe(false); +// expect(F.any.js).toBe('F'); +// expect(F.self.any.js).toBe('___as_vertex'); +// expect(F.self.self.any.js).toBe('F'); +// expect([...F.self.traverse()].map(ref => ref.self.any.js)).toEqual(['F']); +// expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); +// }); +// test("A.equiv(B).equiv(C).equiv(D).equiv(E).equiv(F)", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// const D = Ray.vertex().o({ js: 'D' }).as_reference().o({ js: 'D.#' }); +// const E = Ray.vertex().o({ js: 'E' }).as_reference().o({ js: 'E.#' }); +// const F = Ray.vertex().o({ js: 'F' }).as_reference().o({ js: 'F.#' }); +// +// /** +// * | +// * [--A--] +// * | +// * [--B--] +// * | +// * [--C--] +// * | +// * [--D--] +// * | +// * [--E--] +// * | +// * [--F--] +// * | +// */ +// A.equivalent(B).equivalent(C).equivalent(D).equivalent(E).equivalent(F); +// +// expect(A.type).toBe(RayType.VERTEX); +// expect(A.self.type).toBe(RayType.VERTEX); +// +// expect(A.is_none()).toBe(false); +// expect(A.any.js).toBe('A'); +// expect(A.self.any.js).toBe('___as_vertex'); +// expect(A.self.self.any.js).toBe('A'); +// expect([...A.self.traverse()].map(ref => ref.self.any.js)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); +// expect([...A.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['A']); +// +// expect(B.type).toBe(RayType.VERTEX); +// expect(B.self.type).toBe(RayType.VERTEX); +// expect(B.is_none()).toBe(false); +// expect(B.any.js).toBe('B'); +// expect(B.self.any.js).toBe('___as_vertex'); +// expect(B.self.self.any.js).toBe('B'); +// expect([...B.self.traverse()].map(ref => ref.self.any.js)).toEqual(['B', 'C', 'D', 'E', 'F']); +// expect([...B.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['B', 'A']); +// +// expect(C.type).toBe(RayType.VERTEX); +// expect(C.self.type).toBe(RayType.VERTEX); +// expect(C.is_none()).toBe(false); +// expect(C.any.js).toBe('C'); +// expect(C.self.any.js).toBe('___as_vertex'); +// expect(C.self.self.any.js).toBe('C'); +// expect([...C.self.traverse()].map(ref => ref.self.any.js)).toEqual(['C', 'D', 'E', 'F']); +// expect([...C.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['C', 'B', 'A']); +// +// expect(D.type).toBe(RayType.VERTEX); +// expect(D.self.type).toBe(RayType.VERTEX); +// expect(D.is_none()).toBe(false); +// expect(D.any.js).toBe('D'); +// expect(D.self.any.js).toBe('___as_vertex'); +// expect(D.self.self.any.js).toBe('D'); +// expect([...D.self.traverse()].map(ref => ref.self.any.js)).toEqual(['D', 'E', 'F']); +// expect([...D.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['D', 'C', 'B', 'A']); +// +// expect(E.type).toBe(RayType.VERTEX); +// expect(E.self.type).toBe(RayType.VERTEX); +// expect(E.is_none()).toBe(false); +// expect(E.any.js).toBe('E'); +// expect(E.self.any.js).toBe('___as_vertex'); +// expect(E.self.self.any.js).toBe('E'); +// expect([...E.self.traverse()].map(ref => ref.self.any.js)).toEqual(['E', 'F']); +// expect([...E.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['E', 'D', 'C', 'B', 'A']); +// +// expect(F.type).toBe(RayType.VERTEX); +// expect(F.self.type).toBe(RayType.VERTEX); +// expect(F.is_none()).toBe(false); +// expect(F.any.js).toBe('F'); +// expect(F.self.any.js).toBe('___as_vertex'); +// expect(F.self.self.any.js).toBe('F'); +// expect([...F.self.traverse()].map(ref => ref.self.any.js)).toEqual(['F']); +// expect([...F.self.traverse(Ray.directions.previous)].map(ref => ref.self.any.js)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']); +// }); +// // test(".None.#.equivalent(.vertex.#)", () => { +// // const A = Ray.None().as_reference(); +// // const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// // +// // // const ret = A.equivalent(B); +// // +// // // expect() +// // }); +// test("[A, B, C][.as_array, ...]", () => { +// const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); +// const B = Ray.vertex().o({ js: 'B' }).as_reference().o({ js: 'B.#' }); +// const C = Ray.vertex().o({ js: 'C' }).as_reference().o({ js: 'C.#' }); +// +// A.compose(B).compose(C); +// +// expect(A.as_array().map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); +// expect(B.as_array().map(ref => ref.any.js)).toEqual(['B', 'C']); +// expect(C.as_array().map(ref => ref.any.js)).toEqual(['C']); +// +// expect([...A].map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); +// expect([...A.all().js]).toEqual(['A', 'B', 'C']); +// expect([...A.as_generator()].map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); +// expect(A.as_string()).toBe('A,B,C'); +// +// { +// +// const iterator = A.as_iterator(); +// +// let array: Ray[] = []; +// +// while (true) { +// let current = iterator.next(); +// if (current.done) +// break; +// +// array.push(current.value); +// } +// +// expect(array.map(ref => ref.any.js)).toEqual(['A', 'B', 'C']); +// +// } +// +// // TODO async_generator / async_iterator / for await * +// }); +// test(".next", () => { +// let A = Ray.vertex().o({ js: 'A' }).as_reference(); +// let B = Ray.vertex().o({ js: 'B'}).as_reference(); +// +// A.compose(B); +// +// B = A.next(); +// +// expect(B.type).toBe(RayType.VERTEX); +// expect(B.any.js).toBe('B'); +// expect(B.self +// .initial.self.initial +// .as_reference().any.js +// ).toBe('A'); +// expect(B.self +// .initial.self.initial +// .terminal.self.terminal +// .as_reference().any.js +// ).toBe('B'); +// }); +// test(".vertex.#.compose(.vertex.#)", () => { +// let A = Ray.vertex().o({ js: 'A' }).as_reference(); +// let B = Ray.vertex().o({ js: 'B'}).as_reference(); +// +// B = A.compose(B); +// +// expect(B.type).toBe(RayType.VERTEX); +// expect(B.any.js).toBe('B'); +// expect(B.self +// .initial.self.initial +// .as_reference().any.js +// ).toBe('A'); +// expect(B.self +// .initial.self.initial +// .terminal.self.terminal +// .as_reference().any.js +// ).toBe('B'); +// }); +// // TODO: .compose(), should take everything at the vertex instead. +// // test("[.vertex.#, .vertex.#].#.compose", () => { +// // let A = Ray.vertex().o({ js: 'A' }).as_reference(); +// // let B = Ray.vertex().o({ js: 'B' }).as_reference(); +// // +// // B = new Ray({ +// // initial: A.as_arbitrary(), +// // terminal: B.as_arbitrary() +// // }).as_reference().compose(); +// // +// // expect(B.type).toBe(RayType.VERTEX); +// // expect(B.any.js).toBe('B'); +// // expect(B.self +// // .initial.self.initial +// // .as_reference().any.js +// // ).toBe('A'); +// // expect(B.self +// // .initial.self.initial +// // .terminal.self.terminal +// // .as_reference().any.js +// // ).toBe('B'); +// // }); +// // test(".vertex.#.debug", () => { TODO +// // const a = Ray.vertex().as_reference(); +// // const b = Ray.vertex().as_reference(); +// // a.compose(b); +// // +// // const debug = {}; +// // a.debug(debug); +// // +// // expect(debug).toEqual('') +// // }) +// test(".as_arbitrary", () => { +// expect(Ray.vertex().o({ js: 'A' }).as_arbitrary()().as_reference().any.js).toBe('A'); +// }); +// test(".dereference", () => { +// const A = Ray.vertex( +// Ray.vertex().o({ js: "A.vertex" }).as_arbitrary() +// ).o({ js: 'A' }).as_reference(); +// +// expect(A.dereference.any.js).toBe('A.vertex'); +// expect(A.as_reference().dereference.any.js).toBe('A'); +// expect(A.as_reference().as_reference().dereference.dereference.any.js).toBe('A'); +// expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.any.js).toBe('A'); +// expect(A.as_reference().as_reference().as_reference().dereference.dereference.dereference.dereference.any.js).toBe('A.vertex'); +// }); +// test(".o", () => { +// const ray = Ray.vertex().o({ +// a: 'b', +// position: [0, 1, 2], +// func: () => 'c' +// }).as_reference(); +// +// expect(ray.any.a).toBe('b'); +// expect(ray.any.test).toBe(undefined); +// expect(() => ray.any.undefinedFunction()).toThrow(); +// expect(ray.any.position).toEqual([0, 1, 2]); +// expect(ray.any.func()).toBe('c'); +// }) +// test(".vertex.#", () => { +// /** [--|--] */ const vertex = Ray.vertex().as_reference(); +// +// expect(vertex.type).toBe(RayType.VERTEX); +// +// expect(vertex.is_none()).toBe(false); +// expect(vertex.is_some()).toBe(true); +// +// expect(vertex.is_initial()).toBe(false); +// expect(vertex.is_vertex()).toBe(true); +// expect(vertex.is_terminal()).toBe(false); +// expect(vertex.is_reference()).toBe(false); +// +// expect(vertex.self).toBe(vertex.self.initial.terminal); +// expect(vertex.self).toBe(vertex.self.terminal.initial); +// expect(vertex.self).toBe(Ray.directions.previous(vertex).self.terminal); +// }); +// test(".vertex.initial.#", () => { +// /** [--|--] */ const vertex = Ray.vertex(); +// /** [ |--] */ const initial = vertex.initial.as_reference(); +// +// expect(initial.self.initial.is_none()).toBe(true); +// expect(initial.self).not.toBe(initial.self.self); // If self-referential, that means none. +// +// expect(initial.self.terminal).toBe(vertex); +// expect(initial.self.terminal.self).not.toBe(vertex); +// expect(initial.self.terminal.initial).toBe(initial.self); +// +// expect(initial.self.is_none()).toBe(false); +// expect(initial.self.self.is_none()).toBe(true); +// +// expect(initial.is_some()).toBe(true); +// expect(initial.self.terminal.is_none()).toBe(false); +// +// expect(initial.is_initial()).toBe(true); +// expect(initial.is_vertex()).toBe(false); +// expect(initial.is_terminal()).toBe(false); +// expect(initial.is_reference()).toBe(false); +// expect(initial.type).toBe(RayType.INITIAL); +// }); +// test(".initial.#", () => { +// /** [ |-?] */ const initial = Ray.initial().as_reference(); +// +// expect(initial.self.initial.is_none()).toBe(true); +// expect(initial.self).not.toBe(initial.self.self); // If self-referential, that means none. +// +// expect(initial.self).toBe(initial.self.terminal.initial); +// expect(initial.self.terminal).toBe(initial.self.terminal.terminal.initial); +// +// expect(initial.self.terminal.initial).toBe(initial.self); +// +// expect(initial.self.is_none()).toBe(false); +// expect(initial.self.self.is_none()).toBe(true); +// +// expect(initial.is_some()).toBe(true); +// expect(initial.self.terminal.is_none()).toBe(false); +// +// expect(initial.is_initial()).toBe(true); +// expect(initial.is_vertex()).toBe(false); +// expect(initial.is_terminal()).toBe(false); +// expect(initial.is_reference()).toBe(false); +// expect(initial.type).toBe(RayType.INITIAL); +// }); +// test(".vertex.terminal.#", () => { +// /** [--|--] */ const vertex = Ray.vertex(); +// /** [ |--] */ const terminal = vertex.terminal.as_reference(); +// +// expect(terminal.self.terminal.is_none()).toBe(true); +// expect(terminal.self).not.toBe(terminal.self.self); // If self-referential, that means none. +// +// expect(terminal.self.initial).toBe(vertex); +// expect(terminal.self.initial.self).not.toBe(vertex); +// expect(terminal.self.initial.terminal).toBe(terminal.self); +// +// expect(terminal.self.is_none()).toBe(false); +// expect(terminal.self.self.is_none()).toBe(true); +// +// expect(terminal.is_some()).toBe(true); +// expect(terminal.self.initial.is_none()).toBe(false); +// +// expect(terminal.is_terminal()).toBe(true); +// expect(terminal.is_vertex()).toBe(false); +// expect(terminal.is_initial()).toBe(false); +// expect(terminal.is_reference()).toBe(false); +// expect(terminal.type).toBe(RayType.TERMINAL); +// }); +// test(".terminal.#", () => { +// /** [--| ] */ const terminal = Ray.terminal().as_reference(); +// +// expect(terminal.self.terminal.is_none()).toBe(true); +// expect(terminal.self).not.toBe(terminal.self.self); // If self-referential, that means none. +// +// expect(terminal.self).toBe(terminal.self.initial.terminal); +// expect(terminal.self.initial).toBe(terminal.self.initial.initial.terminal); +// +// expect(terminal.self.initial.terminal).toBe(terminal.self); +// +// expect(terminal.self.is_none()).toBe(false); +// expect(terminal.self.self.is_none()).toBe(true); +// +// expect(terminal.is_some()).toBe(true); +// expect(terminal.self.initial.is_none()).toBe(false); +// +// expect(terminal.is_terminal()).toBe(true); +// expect(terminal.is_vertex()).toBe(false); +// expect(terminal.is_initial()).toBe(false); +// expect(terminal.is_reference()).toBe(false); +// expect(terminal.type).toBe(RayType.TERMINAL); +// }); +// test(".None", () => { +// /** [ ] */ +// const ray = Ray.None(); +// +// expect(ray.self.is_none()).toBe(true); +// expect(ray.self.is_some()).toBe(false); +// expect(ray.self.initial.is_none()).toBe(true); +// expect(ray.self.vertex.is_none()).toBe(true); +// expect(ray.self.terminal.is_none()).toBe(true); +// +// expect(ray.is_none()).toBe(true); +// expect(ray.is_some()).toBe(false); +// +// expect(ray.is_initial()).toBe(false); +// expect(ray.is_vertex()).toBe(true); +// expect(ray.is_terminal()).toBe(false); +// expect(ray.is_reference()).toBe(false); +// expect(ray.type).toBe(RayType.VERTEX); +// +// }); +// test(".None.#", () => { +// /** +// * [ | ] +// * | +// * [?????] +// */ +// +// const ray = Ray.None().as_reference(); +// +// expect(ray.self.is_none()).toBe(true); +// expect(ray.self.is_some()).toBe(false); +// expect(ray.self.initial.is_none()).toBe(true); +// expect(ray.self.vertex.is_none()).toBe(true); +// expect(ray.self.terminal.is_none()).toBe(true); +// +// expect(ray.is_none()).toBe(true); +// expect(ray.is_some()).toBe(false); +// +// expect(ray.is_initial()).toBe(false); +// expect(ray.is_vertex()).toBe(true); +// expect(ray.is_terminal()).toBe(false); +// expect(ray.is_reference()).toBe(false); +// expect(ray.type).toBe(RayType.VERTEX); +// +// }); +// test(".None.#.#", () => { +// /** +// * [ | ] +// * | +// * [ | ] +// * | +// * [?????] +// */ +// const ray = Ray.None().as_reference().as_reference(); +// +// expect(ray.self.is_none()).toBe(true); +// expect(ray.self.is_some()).toBe(false); +// +// expect(ray.self.initial.is_none()).toBe(true); +// expect(ray.self.vertex.is_none()).toBe(true); +// expect(ray.self.terminal.is_none()).toBe(true); +// +// expect(ray.is_none()).toBe(false); +// expect(ray.is_some()).toBe(true); +// +// expect(ray.is_initial()).toBe(true); +// expect(ray.is_vertex()).toBe(false); +// expect(ray.is_terminal()).toBe(true); +// expect(ray.is_reference()).toBe(true); +// expect(ray.type).toBe(RayType.REFERENCE); +// }); +// test(".None.#.#.#", () => { +// /** +// * ... +// * | +// * [ | ] +// * | +// * [ | ] +// * | +// * [ | ] +// * | +// * [?????] +// */ +// let ray = Ray.None().as_reference().as_reference().as_reference(); +// +// expect(ray.self.is_none()).toBe(false); +// expect(ray.self.is_some()).toBe(true); +// expect(ray.self.initial.is_none()).toBe(true); +// expect(ray.self.vertex.is_none()).toBe(true); +// expect(ray.self.terminal.is_none()).toBe(true); +// +// expect(ray.is_none()).toBe(false); +// expect(ray.is_some()).toBe(true); +// +// expect(ray.is_initial()).toBe(true); +// expect(ray.is_vertex()).toBe(false); +// expect(ray.is_terminal()).toBe(true); +// expect(ray.is_reference()).toBe(true); +// expect(ray.type).toBe(RayType.REFERENCE); +// }); +// test(".None.#.#.#.#[4-15]", () => { +// /** +// * Basically the empty value is out of scope of our direct drill, and we expect this behavior 'infinitely' up the reference stack. +// * ... +// * [ | ] <-- ray +// * | +// * [ | ] <-- ray.self - (ray.self.is_none()) +// * | +// * [ | ] <-- ray.self.self - (ray.self.self === ray.self.self.self) +// * | +// * [ | ] <-- ray.self.self.self - = false +// * | +// * [?????] +// */ +// for (let i = 4; i <= 15; i++) { +// let ray = Ray.None(); +// for (let j = 0; j < i; j++) { +// ray = ray.as_reference(); +// } +// +// expect(ray.self.is_none()).toBe(false); +// expect(ray.self.is_some()).toBe(true); +// expect(ray.self.initial.is_none()).toBe(true); +// expect(ray.self.vertex.is_none()).toBe(false); +// expect(ray.self.terminal.is_none()).toBe(true); +// +// expect(ray.is_none()).toBe(false); +// expect(ray.is_some()).toBe(true); +// +// expect(ray.is_initial()).toBe(true); +// expect(ray.is_vertex()).toBe(false); +// expect(ray.is_terminal()).toBe(true); +// expect(ray.is_reference()).toBe(true); +// expect(ray.type).toBe(RayType.REFERENCE); +// } +// }); }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 5b6d53d..2111a5e 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,1497 +1,163 @@ -import _ from "lodash"; -import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; -import {InterfaceOptions} from "./OrbitMinesExplorer"; import JS from "./JS"; +import {NotImplementedError} from "./errors/errors"; +export namespace Rays { -// TODO: SHOULDNT CLASSIFY THESE? (And incorporate in Ray??) -export enum RayType { - // NONE = ' ', - REFERENCE = 'REFERENCE: | ', - INITIAL = 'INITIAL: |-?', - TERMINAL = 'TERMINAL: ?-| ', - VERTEX = 'VERTEX: --|--', -} -export type Boundary = RayType.INITIAL | RayType.TERMINAL; -const opposite = (boundary: Boundary): Boundary => boundary === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL; - -export type SwitchCases< - T = Ray, - SwitchCase extends string | symbol | number = RayType, - TResult = string | ((self: T) => T) -> = { - [TCase in SwitchCase]?: TResult -} - -/** - * https://en.wikipedia.org/wiki/Homoiconicity - */ -export interface PossiblyHomoiconic> { - get self(): T; - is_reference: () => boolean - as_reference: () => T -} - -export interface AbstractDirectionality { - get initial(): T, - get vertex(): T, - get terminal(): T -} - -// TODO: better debug -export type DebugResult = { [label: string]: DebugRay } -export type DebugRay = { - label: string, - initial: string, - vertex: string, - terminal: string, - is_initial: boolean, - is_vertex: boolean, - is_terminal: boolean, - type: RayType, - _dirty_store: any -} - -/** - * JavaScript wrapper for a mutable value. It is important to realize that this is merely some simple JavaScript abstraction, and anything is assumed to be inherently mutable. - * - * All the methods defined here should be considered deprecated, are there to help with JavaScript implementation only. - * - * TODO: - * - Homotopy equivalence merely as some direction/reversibility constraint on some direction, ignoring additional structure (or incorporating it into the equiv) at the vertices. (Could be loosened where certain vertex-equivalences are also part of the homotopy) - * - Induced ignorance/equivalence along arbitrary rays. - * - Usual way of thinking about vertices is what the coninuations are here - phrase that somewhjere - * - * TODO: Any javascript class, allow warpper of function names around any ray, as a possible match - * TODO: All the methods defined here should be implemented in some Ray structure at some point - * - * TODO: Maybe want a way to destroy from one end, so that if other references try to look, they won't find additional structure. - More as a javascript implementation quirck if anything? - * - * TODO: Can do some workaround overloading through properties, at least for +/- - * - * TODO: Singlke keybind for now to show/hide the ray disambiguation or 'dead edges/..'/ - * - * - * - * TODO: All methods to 'step' variant - and an intuitive way to switch between modes - * - Through better Ray.___func - * - Transform all functions on Ray to that. (Perhaps use JavaScript generators by default (more intuitively?) - Just convert using JS.Generator) - * - No assumption of halting - * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence - * - * TODO: Stylistic - * - Consistency of Arbitrary vs non-arbitrary. - * - Reorder methods in a sensible way. - * - */ -export class Ray // Other possibly names: AbstractDirectionality, ..., ?? - implements - AbstractDirectionality, - PossiblyHomoiconic, - - AsyncIterable, - Iterable - // Array - // Dict -{ - // TODO: Could make a case that setting the terminal is more of a map, defaulting/first checking the terminal before additional functionality is mapped over that. - - protected _initial: JS.Arbitrary; get initial(): Ray { return this._initial(); } set initial(initial: JS.Arbitrary) { this._initial = initial; } - protected _vertex: JS.Arbitrary; get vertex(): Ray { return this._vertex(); } set vertex(vertex: JS.Arbitrary) { this._vertex = vertex; } - protected _terminal: JS.Arbitrary; get terminal(): Ray { return this._terminal(); } set terminal(terminal: JS.Arbitrary) { this._terminal = terminal; } - - get self(): Ray { return this.vertex; }; set self(self: JS.Arbitrary) { this.vertex = self; } - - constructor({ initial, vertex, terminal, }: { - initial?: JS.Arbitrary, - vertex?: JS.Arbitrary, - terminal?: JS.Arbitrary, - } = {}) { - this._initial = initial ?? Ray.None; - this._vertex = vertex ?? this.self_reference; // TODO: None, could also self-reference the ray on which it's defining to be None. Now it's just an ignorant loop. - this._terminal = terminal ?? Ray.None; + export type Constructor = { + initial: JS.FunctionConstructor, + vertex: JS.FunctionConstructor, + terminal: JS.FunctionConstructor, } - /** [ |-?] */ is_initial = (): boolean => this.is_some() && this.self.initial.is_none(); - /** [--|--] */ is_vertex = (): boolean => !this.is_initial() && !this.is_terminal(); - /** [?-| ] */ is_terminal = (): boolean => this.is_some() && this.self.terminal.is_none(); - /** [ | ] */ is_reference = (): boolean => this.is_initial() && this.is_terminal(); - /** [?-| ] or [ |-?] */ is_boundary = (): boolean => !this.is_reference() && (this.is_initial() || this.is_terminal()); // TODO: IS !This.references necessary? - - get type(): RayType { - /** [ | ] */ if (this.is_reference()) return RayType.REFERENCE; - /** [ |-?] */ if (this.is_initial()) return RayType.INITIAL; - /** [?-| ] */ if (this.is_terminal()) return RayType.TERMINAL; - // /** [ ] */ if (this.is_empty()) return RayType.NONE; - /** [--|--] */ return RayType.VERTEX; - } - - /** - * This is basically what breaks the recursive structure. Imagine a Ray like this: [|--|--|]. There are several ways of interpreting it, either there's a boolean on initial, vertex, terminal; Some 'false' value, says there's nothing there. Some true value says there's something there. - Basically an Option, ..., Maybe as in certain languages. - * - * --- - * - * Another way of interpreting a possible way of implementing it, is no matter how much more detail we would like to ask, the only thing we ever see is the same structure again (if we ignore the difference of us asking about that additional structure, that's still a possible handle on some difference). - * - * As a way of saying/.../assuming: I only 'infinitely' assume it's only this structure, "it seems to halt here". Note that this is necessarily an assumption. No guarantee of this can be made. This is necessarily an equivalence, ..., ignorance. - * - * See more: https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. - * - * --- - * - * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. - */ - is_none = (): boolean => Ray.is_orbit(this.self, this.self.self); - - /** - * Tries for "global coherence" - since we probably can't actually do that, practically this just means self-reference, were no change is assumed... - * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. - */ - static is_orbit = (a: Ray, b: Ray) => a === b; // is, ..., appears equal. - protected get self_reference() { return this.as_arbitrary(); }; - - is_some = (): boolean => !this.is_none(); - /** - * Can be used to override default dereference behavior. - * - * TODO: This should probably be configurable on a more global setting. - * - * TODO: Difference between this.self and this.self.self.as_reference is??? + * TODO: Shouldn't classify these? + * TODO: Incorporate into Ray? */ - get dereference() { return this.self.self.as_reference(); } - - // /** - // * Moves `this.self` and `this.self.self` to a new line. - // * - // * [ |--] this.self ----- this.self.self [--|--] - // * ______ (<- initial pointer) - // */ - // as_initial = (): Ray => { - // if (this.is_none()) { - // throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); - // } - // if (this.dereference.is_none()) { - // // TODO: Need some intuition for this check - // const vertex = this.___as_vertex(); - // - // if (vertex.type !== RayType.VERTEX) - // throw new PreventsImplementationBug(); - // - // return vertex.follow(Ray.directions.previous); - // } - // - // const [terminal_vertex, initial_vertex] = this.___as_vertices(); - // - // if (initial_vertex.type !== RayType.VERTEX) - // throw new PreventsImplementationBug(); - // if (terminal_vertex.type !== RayType.VERTEX) - // throw new PreventsImplementationBug(); - // - // initial_vertex.compose(terminal_vertex); - // - // // TODO BETTER DEBUG - // - // return initial_vertex.follow(Ray.directions.previous); - // } - /** - * Moves `this.self` and `this.self.self` to a new line. - * - * [ |--] this.self.self ----- this.self [--|--] - * _____ (<- terminal pointer) - */ - as_terminal = (): Ray => { - if (this.is_none()) { - throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); - } - if (this.dereference.is_none()) { - throw new PreventsImplementationBug(); - } - - const [terminal_vertex, initial_vertex] = this.___as_vertices(); - - if (initial_vertex.type !== RayType.VERTEX) - throw new PreventsImplementationBug(); - if (terminal_vertex.type !== RayType.VERTEX) - throw new PreventsImplementationBug(); - - initial_vertex.compose(terminal_vertex); - - // TODO BETTER DEBUG - - return terminal_vertex.follow(); - } - private ___as_vertices = (): [Ray, Ray] => { - if (!Ray.is_orbit(this.self, this.self.self.self)) - throw new PreventsImplementationBug('Is there a use-case for this? Probably not?'); //TODO - - // TODO NOTE: THE ORDER OF `this.self` first matters here. - return [this.self.___as_vertex(), this.___as_vertex()]; - } - private ___as_vertex = (): Ray => { - const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); - - return this.___ignorantly_equivalent(vertex); - } - ___ignorantly_equivalent = (ref: Ray): Ray => { - ref.self.self = this.self.as_arbitrary(); - this.self.self = ref.self.as_arbitrary(); - - return ref; - } - - /** [ ] */ static None = () => new Ray({ }).o({ }); - /** [--?--] */ static vertex = (value: JS.Arbitrary = Ray.None) => { - /** [ ] */ const vertex = Ray.None(); - /** [-- ] */ vertex.initial = vertex.___empty_initial(); - /** [ ? ] */ vertex.vertex = value; - /** [ --] */ vertex.terminal = vertex.___empty_terminal(); - - /** [--?--] */ return vertex; + export enum Type { + REFERENCE = '(REFERENCE: [ | ])', + INITIAL = '(INITIAL: [ |-?]', + TERMINAL = '(TERMINAL: [?-| ])', + VERTEX = '(VERTEX: [--|--])', } - /** [ |-?] */ static initial = () => Ray.vertex().initial; - /** [?-| ] */ static terminal = () => Ray.vertex().terminal; - // TODO; Temp placeholders for now - & BETTER DEBUG - ___empty_initial = () => new Ray({ vertex: Ray.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); - ___empty_terminal = () => new Ray({ vertex: Ray.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); + export type Boundary = Type.INITIAL | Type.TERMINAL; - /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ - /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); - - // TODO: Difference between () => this & this.as_arbitrary , relevant for lazy/modular/ignorant structures etc.. - as_arbitrary = (): JS.Arbitrary => () => this; + export const New = (constructor?: Rays.Constructor): Ray => Rays.Instance.New(constructor).proxy; /** - * TODO : COMPOSE EMPTY AS FIRST ELEMENT: - * if (initial.is_none()) { - * // 'Empty' vertex from this perspective. - * - * initial.vertex = terminal.as_arbitrary(); - * console.log('first element'); - * return terminal; - * } + * An uninitialized empty Ray, which caches itself once initialized. */ + export const None: JS.FunctionConstructor = JS.Function.CachedAfterUse(Rays.New); - // TODO: Test if references hold after equivalence/composition... + export class Instance { + static New = (constructor?: Rays.Constructor): Rays.Instance => new Rays.Instance(constructor); - // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? - // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? + protected readonly _proxy: Ray; - // TODO: Should do, one timesteap ahead, collapse one reference, and then recursively call continues_with on the vlaue at the reference, until it yields something. + /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ + get initial(): Ray { return this._initial.call(this.proxy); } set initial(initial: JS.FunctionConstructor) { this._initial = JS.Function.New(initial); } protected _initial: JS.Function; + /** An arbitrary Ray, defining what our current position is equivalent to. */ + get self(): Ray { return this._self.call(this.proxy); } set self(self: JS.FunctionConstructor) { this._self = JS.Function.New(self); } protected _self: JS.Function; + /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ + get terminal(): Ray { return this._terminal.call(this.proxy); } set terminal(terminal: JS.FunctionConstructor) { this._terminal = JS.Function.New(terminal); } protected _terminal: JS.Function; - // TODO AS += through property - // TODO: Generally, return something which knows where all continuations are. - // @alias('merge, 'continues_with', 'compose') - /** - * Compose as "Equivalence at Continuations": (can usually be done in parallel - not generally) - * - `A.compose(B)` = `(A.TERMINAL).equivalent(B.INITIAL)` - * - `A.compose(B).compose(C)` = `(A.TERMINAL).equivalent(B.INITIAL) & (B.TERMINAL).equivalent(C.INITIAL)` - * - * Another interesting connection: - * - `A.compose(B).compose(C)` = `(A.equivalent(B).equivalent(C)).dereference.(MISSING ALL FUNC).compose` - * - * @see "Continuations as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence - */ - static compose = JS.Function.Impl((initial, terminal) => { + get proxy(): Ray { return this._proxy; } - if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) - throw new PreventsImplementationBug(); - - // ${[...initial.self.initial.as_reference().all().js]} - if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) { - throw new PreventsImplementationBug(`[${initial.type}] - [${terminal.type}] - only composing vertices for now (${initial.self.initial.any.js} -> ${terminal.self.terminal.any.js})`); + protected constructor({ initial, vertex, terminal }: Partial = {}) { + this._proxy = new Proxy(this as unknown as Ray, Rays.ProxyHandler); + this._initial = JS.Function.New(initial ?? Rays.None); + this._self = JS.Function.New(vertex ?? this.proxy); + this._terminal = JS.Function.New(terminal ?? Rays.None); } - initial.follow().equivalent(terminal.follow(Ray.directions.previous)); - - // return ref; TODO - return terminal; - }); - compose = Ray.compose.as_method(this); - - // TODO: Cleanup - /** - * Equivalence as "Composing Vertices": "TODO: Is this right?: Equivalence at Continuations, inside a Vertex, is parallel composition, from the perspective of the usual direction defined at the Vertex (not generally parallel)" - * - `A.equivalent(B)` = `A.as_vertex().compose(B.as_vertex())` - * - `A.equivalent(B).equivalent(C)` = `A.as_vertex().compose(B.as_vertex()).compose(C.as_vertex())` - * - * An equivalence is best understood as the drawing of a single line between two things. Where those two things might have arbitrary structure around them, but we're not checking the (non-)existence of that structure. And thus: - * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. (or: Changes of an equivalence are only applied locally, which could have global effects, but this isn't necessarily obvious). - * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies - */ - static equivalent = JS.Function.Impl((initial, terminal) => { - /** - * The simplest case, is where both sides are only aware of themselves (on .vertex). The only thing we need to do is turn an Orbit, to an Orbit which repeats every 2 steps, the intermediate step being the other thing. - * - * Or in textual terms something like: - * - A single Orbit: `(A.self = A) | (B.self = B)` (i.e. A.is_none && B.is_none) - * - To: `(A.self = B) | (B.self = A)` - * - * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. + * Used to jump out of the proxy. */ - const ignorant_equivalence = (): Ray => { - return initial.___ignorantly_equivalent(terminal); - } - - // 2x Ray.None -> Turn into 2 empty references, referencing each-other. - if ( - initial.dereference.is_none() && terminal.dereference.is_none() - && !(initial.type === RayType.VERTEX && terminal.type === RayType.VERTEX) - ) { - // throw new PreventsImplementationBug(`${initial.type} / ${terminal.type}`) - return ignorant_equivalence(); - } + get ___instance(): Instance { return this; } + } - // Two structures, which have `ref.self = Ray.None` -> Turn into two structures which are on a line in between them. - if (initial.dereference.is_none()) { - const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); - vertex.self.self = initial.self.as_arbitrary(); - initial.self.self = vertex.self.as_arbitrary(); + export const ProxyHandler: ProxyHandler = { + get: (self: Instance, property: string | symbol, proxy: Ray): any => { + /** Use any field defined on {Rays.Instance} first. */ + const field = (self as any)[property]; + if (field) { return field; } - // initial.equivalent(terminal); - // return terminal; - } - if (terminal.dereference.is_none()) { - const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); - vertex.self.self = terminal.self.as_arbitrary(); - terminal.self.self = vertex.self.as_arbitrary(); + /** Otherwise, switch to functions defined on {Rays.Functions} */ + const func = Rays.Function(property); + if (func) { return func.as_method(self.proxy); } - // initial.equivalent(terminal.___as_vertex()); - // return terminal; - } + /** Not implemented. */ + throw new NotImplementedError(`Called property '${String(property)}' on Ray, which has not been implemented.`); + }, - if (initial.is_boundary() && initial.dereference.is_boundary()) { + apply: (self: Instance, thisArg: any, argArray: any[]): any => { throw new NotImplementedError(); - initial.as_terminal(); - //.follow(Ray.directions.previous).compose(terminal.dereference); - // return terminal; - } + }, - if ( - initial.dereference.type !== RayType.VERTEX - || terminal.dereference.type !== RayType.VERTEX - || initial.dereference.self === initial.self - || terminal.dereference.self === terminal.self - ) { - throw new PreventsImplementationBug(` - [${initial.type}](${initial.follow_direction().any.js}) - / [${initial.dereference.type}](${initial.dereference.follow_direction().any.js}) - -> ${terminal.type}${terminal.follow_direction().any.js}`) - } - - if (initial.follow().type !== RayType.TERMINAL || terminal.follow(Ray.directions.previous).type !== RayType.INITIAL) { + set: (self: Instance, property: string | symbol, newValue: any, proxy: Ray): boolean => { throw new NotImplementedError(); - initial.dereference.push_back(terminal.dereference); // TODO: NON-PUSH-BACK VARIANT? (Just local splits?) - return terminal; - // throw new PreventsImplementationBug(` - // [${initial.type}](${initial.follow_direction().any.js}) - // / [${initial.dereference.type}] {${[...initial.dereference.traverse()].map(ref => ref.self.follow_direction().any.js)}} - // -> ${terminal.type} (${terminal.follow_direction().any.js}) - // / [${terminal.dereference.type}]`) - } - - // if (terminal.self.any.js === 'D') - // throw new PreventsImplementationBug(); - - initial.dereference.compose(terminal.dereference); - - return terminal; - - // initial.dereference.compose() - // return terminal; - }); - equivalent = Ray.equivalent.as_method(this); - - // static equivalent = Ray.___func(ref => { - // let { initial, terminal} = ref.self; - // - // /** - // * The simplest case, is where both sides are only aware of themselves (on .vertex). The only thing we need to do is turn an Orbit, to an Orbit which repeats every 2 steps, the intermediate step being the other thing. - // * - // * Or in textual terms something like: - // * - A single Orbit: `(A.self = A) | (B.self = B)` (i.e. A.is_none && B.is_none) - // * - To: `(A.self = B) | (B.self = A)` - // * - // * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. - // */ - // const ignorant_equivalence = (): Ray => { - // return initial.___ignorantly_equivalent(terminal); - // } - // - // // 2x Ray.None -> Turn into 2 empty references, referencing each-other. - // if (initial.is_none() && terminal.is_none()) - // return ignorant_equivalence(); - // - // // Two structures, which have `ref.self = Ray.None` -> Turn into two structures referencing each-other. - // if (initial.dereference.is_none() && terminal.dereference.is_none()) - // return ignorant_equivalence(); - // - // if ( - // (initial.is_vertex() && terminal.is_boundary()) - // || (terminal.is_vertex() && initial.is_boundary()) - // ) { - // throw new NotImplementedError(`Parallel composition: TODO`); - // } - // - // /** - // * - Splits the 'initial' side's vertex, into an iterable one, and returns a pointer to the initial side of that iterator. - // * - // * - Similarly, we do the opposite for the terminal, returning the terminal side of that iterator. - // * - // * - Then we're left with the 'beginning' of one iterator, and the 'end' of the other. And the only thing that's left to do, is draw a simple (ignorant) equivalence between the two. (Basically call this function again, and call {ignorant_equivalence}). - // * TODO: This could also be a line with some debug information. - // */ - // const a = initial.as_terminal(); - // const b = terminal.as_initial(); - // - // if (a.type !== RayType.TERMINAL) - // throw new PreventsImplementationBug(); - // if (b.type !== RayType.INITIAL) - // throw new PreventsImplementationBug(); - // - // if (!a.self.self.is_none()) - // throw new PreventsImplementationBug(`${b.self.self.any.js}`); - // if (!b.self.self.is_none()) - // throw new PreventsImplementationBug(`${b.self.self.any.js}`); - // - // a.equivalent(b); - // - // const ret = terminal; - // - // if (ret.type !== RayType.VERTEX) - // throw new PreventsImplementationBug(`${ret.type}`); - // - // return ret; - // }); - // equivalent = Ray.equivalent.as_method(this); - - // zip also compose??? - // [a, b, c] zip [d, e, f] zip [g, h, i] ... - // [[a,d,g],[b,e,h],[c,f,i]] - static zip = JS.Function.Impl((initial, terminal) => { + }, - if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) - throw new PreventsImplementationBug('TODO: Implement'); - - if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) - throw new PreventsImplementationBug('TODO: Implement'); - - throw new NotImplementedError(); - // initial.traverse() - // return new Ray({ - // - // }); - }); - zip = Ray.zip.as_method(this); - - // pop = (): Ray => { - // this.last().previous().all.terminal = (ref) => ref.___empty_terminal(); - // } - pop = (): Ray => this.___primitive_switch({ - [RayType.VERTEX]: () => { - const previous_vertex = this.self.initial.follow(Ray.directions.previous); - - if (this.is_none()) { - return this; // TODO; Already empty, perhaps throw - } - - return previous_vertex.___primitive_switch({ - [RayType.VERTEX]: () => { - console.log(previous_vertex) - // TODO: NONHACKY - - previous_vertex.self.terminal = new Ray({ vertex: Ray.None, initial: previous_vertex.self.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() - return previous_vertex; - } - }); - } - }); - - /** - * Helper methods for commonly used directions - * - * TODO: Link to step-wise walk as any function - lazy, not traversing certain paths, etc.. (for last/..) - */ - static directions = { - next: (ref: Ray) => ref.self.terminal.as_reference(), - previous: (ref: Ray) => ref.self.initial.as_reference(), - none: (ref: Ray) => ref, // Note that "None" is necessarily inconsistent - } - static follow_direction = { - [RayType.INITIAL]: Ray.directions.next, - [RayType.TERMINAL]: Ray.directions.previous - } - - // TODO: Nicer one? ; Differentiate between ".next" and just "follow the pointer" ? - follow = (step: JS.Implementation = Ray.directions.next): Ray => { - // let pointer = new Ray({ - // initial: () => this, - // terminal: () => step(this), - // }); TODO USE POINTER? - - return step(this); - } - follow_direction = (): Ray => this.___primitive_switch({...Ray.follow_direction}); - - /** - * .next - */ - next = (step: JS.Implementation = Ray.directions.next): Ray => { - return [...this.traverse(step)][1] ?? Ray.None(); // TODO BAD - } - has_next = (step: JS.Implementation = Ray.directions.next): boolean => this.next(step).is_some(); - // @alias('end', 'result', 'back') - last = (step: JS.Implementation = Ray.directions.next): Ray => { - const next = this.next(step); - return next.is_some() ? next.last(step) : this; - } - /** - * .previous (Just .next with a `Ray.directions.previous` default) - */ - previous = (step: JS.Implementation = Ray.directions.previous): Ray => this.next(step); - has_previous = (step: JS.Implementation = Ray.directions.previous): boolean => this.has_next(step); - // @alias('beginning', 'front') - first = (step: JS.Implementation = Ray.directions.previous): Ray => this.last(step); - - // TODO: I Don't like this name, but it needs to get across that any equivalency, or any equivalency check for that necessarily, is local. And I want more equivalences, I run more of this method. - // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. - is_vertex_equivalent = (b: Ray) => { - // TODO; in the case of a list, each individually, again, additional structure... - } - // TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? - - // TODO: Whether the thing is referenced on the vertex: do their vertices have some connection onm this direction? - is_equivalent = (b: Ray): boolean => { return false; } // TODOl: Current references assume you can't go inside vertex.. - // TODO implement .not?? - - get count(): Ray { return JS.Number(this.as_array().length); } - - // TODO; Could return the ignorant reference to both instances, or just the result., .. - - /** - * TODO: Need more control over the (non-/)lazyness of copy. - * - * - The problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. - * - * - Additionally, a copy necessarily has some non-redundancy to it: - * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy - */ - // @alias('duplicate') - copy = (): Ray => { - // return this.self.as_reference(); // Copies the reference? - throw new NotImplementedError(); - - // const copy = new Ray({ - // initial: this.self._initial().as_reference().none_or(ref => ref.copy()).as_arbitrary(), - // vertex: this.self._vertex().as_reference().none_or(ref => ref.copy()).as_arbitrary(), - // }).o({ ___dirty_copy_buffer: {} }); - // // copy._initial = () => copy.any.___dirty_copy_buffer._initial ??= this.self._initial().as_reference().copy(); - // // copy._vertex = () => copy.any.___dirty_copy_buffer._vertex ??= this.self._vertex().as_reference().copy(); - // // copy._terminal = () => copy.any.___dirty_copy_buffer._terminal ??= this.self._terminal().as_reference().copy(); - // - // - // // TODO: Doesn't copy .any - // - // return copy.as_reference(); - } - - // none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); - - // @alias('converse', 'opposite', 'swap') - get reverse(): Ray { - const copy = this;//TODO.copy(); - - // TODO: Do we do this lazy by default? Just using refs??? - Or abstract this elsewhere to decide what to do - const swap = copy.initial; - copy.initial = copy.terminal.as_arbitrary(); - copy.terminal = swap.as_arbitrary(); - // TODO: This doesn't actually work - - return copy; - } - - /** - * TODO - Better 'value' here. (Use JS.Any??) - * - * TODO: All these should accept Ray values. - * - * .size, since .length is reserved by JavaScript. - * TODO: .size could be more tensor-like, arbitrary lengths.. - */ - // @alias('length', 'of_length') - static size = (of: number, value: any = undefined): Ray => { - let ret: Ray | undefined; - let current: Ray | undefined; - // TODO: Actual good implementation: Should be lazy - for (let i = 0; i < of; i++) { - const vertex = Ray.vertex().o({js: value}).as_reference(); - - if (!ret) { - current = ret = vertex; - } else { - current = current?.compose(vertex); - } + deleteProperty: (self: Instance, property: string | symbol): boolean => { + throw new NotImplementedError(); } - - if (!ret) - return Ray.None(); - - return ret; - } - static at = (index: number, of: number, value: any = undefined): Ray => { - return Ray.size(of, value).at(index); } - /** - * Just uses length/size for permutation. TODO: More complex permutation/enumeration implementation should follow at some point. (@see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=One%20of%20them%20could%20even%20be%20putting%20both%20our%20points%20on%20our%20selection for an example) - * - * @see "Combinatorics as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Combinatorics%20%2D%20Combinatorics%20as%20Equivalence - */ - static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( - // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) - permutation ?? 0, - // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. - permutation === undefined ? 1 : of - ) - - at = (steps: number | Ray | JS.Arbitrary): Ray => { - if (!JS.is_number(steps)) - throw new NotImplementedError('Not yet implemented for Rays.'); - - // TODO: Actual good implementation - also doesn't support modular like this - const array = [...this.traverse( - steps < 0 ? Ray.directions.previous : Ray.directions.next - )]; - - steps = Math.abs(steps); - return array.length > steps && steps >= 0 ? ( - array[steps] ?? Ray.None() // TODO FIX: Probably a JavaScript quirck with some weird numbers, just failsafe to None. - ) : Ray.None(); - } - - // export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); - - // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' - map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } - // filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } - get clear(): Ray { throw new NotImplementedError(); } - - // TODO: Generalize these functions to: - // - // TODO: +default, in the case of Initial/Terminal = Ray.None, to which the default sometimes is nothing. Or in the case of min/max it's 0. - - - // TODO: being called min.x needs to return the min value within that entire structure. - - // [this.vertices().x.max(), this.edges().x.max()].max() - // [this.vertices().x.min(), this.edges().x.max()].max() - // TODO: Indicies not corresponding the the directionality defined, are probably on another abstraction layer described this way. More accurately, they're directly connected, and on a separate layer with more stuff in between... - get index(): Ray { throw new NotImplementedError(); } - // TODO: Can probably generate these on the fly, or cache them automatically - min = (_default: 0): Ray => { throw new NotImplementedError(); } - max = (_default: 0): Ray => { throw new NotImplementedError(); } - - // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS - // apply = (func: Ray) => { + export const Function = < + TProperty extends keyof typeof Rays.Functions + >(property: string | symbol): (typeof Rays.Functions)[TProperty] | undefined => Rays.Functions[property as TProperty] ?? undefined; + + export namespace Functions { + + /** [ |-?] */ export const is_initial = JS.Function.Self( + self => self.is_some() && self.initial.is_none() + ); + /** [--|--] */ export const is_vertex = JS.Function.Self( + self => !self.is_initial() && !self.is_terminal() + ); + /** [?-| ] */ export const is_terminal = JS.Function.Self( + self => self.is_some() && self.terminal.is_none() + ); + /** [ | ] */ export const is_reference = JS.Function.Self( + self => self.is_initial() && self.is_terminal() + ); + /** [?-| ] or [ |-?] */ export const is_boundary = JS.Function.Self( + self => !self.is_reference() && (self.is_initial() || self.is_terminal()) + ); + + export const type = JS.Function.Self(self => { + /** [ | ] */ if (self.is_reference()) return Rays.Type.REFERENCE; + /** [ |-?] */ if (self.is_initial()) return Rays.Type.INITIAL; + /** [?-| ] */ if (self.is_terminal()) return Rays.Type.TERMINAL; + /** [--|--] */ return Rays.Type.VERTEX; + }); - // TODO: Combine into generalized [x, min/max()] - preserve terminal/initial structure - // TODO: ray#apply. - // TODO: FROM COMPOSER /** - * const func = [min(), '', max()] + * This is basically what breaks the recursive structure. * - * const [min_x, max_x] = [ - * // Compute the min x-coordinate of the edges and vertices in the other graph. - * compose.terminal.x.min(), // min_other + * Tries for "global coherence", practically this just means self-reference, were no change is (inconsistently) assumed... * - * // Compute the max x-coordinate of the edges and vertices in this graph. - * compose.initial.x.max(), // max_self - * ] + * --- + * + * Another way of interpreting a possible way of implementing it, is no matter how much more detail we would like to ask, the only thing we ever see is the same structure again (if we ignore the difference of us asking about that additional structure, that's still a possible handle on some difference). + * + * As a way of saying/.../assuming: I only 'infinitely' assume it's only this structure, "it seems to halt here". Note that this is necessarily an assumption. No guarantee of this can be made. This is necessarily an equivalence, ..., ignorance. + * + * See more: https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. */ - // } - - // ___compute = () - - *traverse(step: JS.Implementation = Ray.directions.next): Generator { - // TODO: Also to ___func?? - - if (this.type !== RayType.VERTEX) - throw new NotImplementedError(`[${this.type}]`); - - yield *this.___next({step}); - } - - static pointer = (initial: Ray, step: JS.Implementation): Ray => new Ray({ - initial: () => initial, - terminal: () => step(initial) - }); - private next_pointer = (step: JS.Implementation) => { - const { self: history, terminal: current } = this; - - return new Ray({ - initial: current.as_arbitrary(), - vertex: history.as_arbitrary(), - terminal: () => current.follow(step) - }); - }; - - *___next({ - step = Ray.directions.next, - } = {}): Generator { - for (let pointer of this.___traverse({step})) { - - // TODO: You can do this non-locally with a pass over the history. This way it's local, but we''ll have to find a good example of why this might not go that well. (As this would match to any empty vertices, and maybe more) - - // TODO: Could also check for none.. - const { initial: previous, terminal: current } = pointer; - - if (previous.is_vertex() && !Ray.is_orbit(previous.self, current)) { - yield pointer.initial; - } - } - } - *___map(map: (vertex: Ray) => T, { - step = Ray.directions.next, - } = {}): Generator { - for (let vertex of this.___next({step})) { - yield map(vertex); - } - } + export const is_none = JS.Function.Self( + self => self.is_orbit(self.self) + ); + export const is_some = JS.Function.Self( + self => !self.is_none() + ); - static *traverse(options = { - initial: Ray.None(), - step: Ray.directions.next, - branch: { - // @alias('pruning', 'mapping', 'filtering') - prune: (branches: Ray): Ray => branches, - // @alias('next', 'selection', 'tactic', 'strategy') - next: (branches: Ray): Ray => branches.first(), - } - }): Generator<{ - branch: Ray, - vertex: Ray, - }> { /** - * An arbitrary Ray of (accessible) (possible) next steps to perform in traversal. + * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. */ - // @alias('cursor(s)', 'branch(es)', 'selection(s)') - let branches: Ray = Ray.None(); - - while (true) { - /** - * Branch *Pruning, Mapping, ..., Filtering* - */ - branches = options.branch.prune(branches); // TODO: Could hold history - - /** - * Branch *Selection, Tactic, ..., Strategy* - */ - - /** - * An arbitrary Ray of (requested) next steps to perform in parallel/.../superposition (with respect to all the other branches). - */ - const branches_to_traverse: Ray = options.branch.next(branches); - - /** - * Make copies of our traversal for each selected branch - */ - // TODO - - /** - * Split off traversal to each branch, selecting their respective . - */ - - let branch: Ray = branches_to_traverse; //TODO - - const initial = branch.previous(); // TODO hold history ; discard more than one step for this implementation, optionally switch - const terminal = branch; - - const step = () => { - const traverse_boundary = (): Ray => { - return branch.___primitive_switch({ - /** - * Dereferencing is likely in many cases quickly subject to infinite stepping (similar to INITIAL -> INITIAL, TERMINAL -> TERMINAL, VERTEX -> VERTEX. (Could be that this means that there's no continuation, a self-reference defined here, or it's some mechanism of halting.) - * - * - TODO: Simple example of infinitely finding terminals, or a reference to 'nothing - infinitely'. - * - TODO: If both are references, allow deref of both? - */ - [RayType.REFERENCE]: (self) => self.dereference, - - /** - * A possible continuation - * INITIAL/TERMINAL -> possible previous - TERMINAL.self.initial (pass to step) - * TERMINAL/INITIAL -> possible next - INITIAL.self.terminal (pass to step) - */ - [RayType.INITIAL]: Ray.follow_direction[RayType.INITIAL], - [RayType.TERMINAL]: Ray.follow_direction[RayType.TERMINAL], - - /** - * This is the most interesting case: Many possible continuations (from the perspective of a boundary (INITIAL/TERMINAL)). - * - * NOTE: - * - There are many ways of actually implementing this. This is one which ensures the checks needed to traverse arbitrary continuations is always local (with the trade-off that you can't disambiguate between structure on edges vs structure on vertices by default). Though this can be imposed with something else. (TODO) - * - * @see = TODO - */ - [RayType.VERTEX]: (terminal) => { - const initial = branch.previous(); - // TODO: Could check if self.self is Orbit. - - /** - * Simplest check, ensure we're coming from some place which splits into many branches - * @see = TODO - */ - if (Ray.is_orbit(initial.self, terminal.self.self)) { - // TODO: Branch to previous.next - throw new NotImplementedError(); - } - - /** - * This is the one which disallows structure on edges, and assumes a vertex it finds, necessarily as additional vertices we're looking for. (But we don't need to keep track of where we are like this ; TODO: Implement variant which checks back over branch.previous() to allow for this) - * @see = TODO - */ - if ( - terminal.dereference.is_boundary() // Whether there's a continuation defined on the vertex. - && Ray.is_orbit(terminal.self, terminal.self.self.self) - ) { - // TODO: Split of options.step(terminal) & new Ray({ - // initial: terminal.as_arbitrary(), - // vertex: pointer.as_arbitrary(), - // terminal: () => terminal.dereference - // }) - throw new NotImplementedError(); - } - - return options.step(terminal); - } - }); - } - - return initial.___primitive_switch({ - [RayType.VERTEX]: (self) => options.step(self), // TODO dereference - [RayType.INITIAL]: (self) => traverse_boundary(), - [RayType.TERMINAL]: (self) => traverse_boundary(), - [RayType.REFERENCE]: (self) => self.dereference, - }); - } - - // After step, if IS_TERMINAL, nothing. assume halting (!!!at prune step ?) - - const terminal = branch.follow(); - - // branch.self = terminal; - - } - } - - /** - * TODO: Not happy with this... - */ - *___traverse({ - step = Ray.directions.next, - filter = (pointer: Ray): boolean => true, - next = (pointers: Ray[]): Ray => pointers[pointers.length - 1], - remove = (pointers: Ray[]) => pointers.pop(), - } = {}): Generator { - const pointers: Ray[] = [ - Ray.vertex(Ray.pointer(this, step).as_arbitrary()) - ]; // TODO COuld be a ray; - - let first = true; - - while (true) { - - const ref = next(pointers); - if (ref === undefined) { - remove(pointers); - // TODO: Could just keep trying... - break; - } - let { self: pointer } = ref; - - if (!filter(pointer)) { - remove(pointers); ///, pointer - first = false; // TODO REMOVE - continue; - } - - if (!first) { // TODO THIS NEEDS TO BE BETTER - pointer = pointer.step(); - } - - yield pointer; - - const { initial, terminal } = pointer; - - if (!first) { - - // TODO: Same pattern as .step - - /** - * VERTEX (current) - * | - * v - * - * ? <-- Pointer B - * [--| ] <-- INITIAL/TERMINAL (previous) - * ? <-- Pointer A - */ - const default_pointer = (): Ray[] => { - return pointer.terminal.is_none() ? [] : [pointer]; - } - const boundary = (boundary: Boundary): Ray[] => { - return terminal.___primitive_switch({ - [boundary]: default_pointer, - [opposite(boundary)]: default_pointer, - [RayType.REFERENCE]: default_pointer, - - [RayType.VERTEX]: () => { - if (Ray.is_orbit(terminal.self.self, initial.self)) { - return [ - this.next_pointer(Ray.directions.previous), - this.next_pointer(Ray.directions.next) - ]; - } - - if (terminal.dereference.is_boundary() && Ray.is_orbit(terminal.self.self.self, terminal.self)) { - - return [ - ...default_pointer(), - new Ray({ - initial: terminal.as_arbitrary(), - vertex: pointer.as_arbitrary(), - terminal: () => terminal.dereference - }) - ] - } - - return default_pointer(); - - // if (terminal.self.is_boundary() && Ray.is_orbit(terminal.self.self.self, terminal.self)) { - // - // return [ - // this.next_pointer(Ray.directions.next), - // this.next(current => current.self.self) - // ] - // } - // - // if (!Ray.is_orbit(terminal.self.self, initial.self)) - // return default_pointer(); - // - // return [ - // this.next_pointer(Ray.directions.previous), - // this.next_pointer(Ray.directions.next) - // ]; - }, - }) - } - - const branches: Ray[] = initial.___primitive_switch({ - [RayType.VERTEX]: (initial) => terminal.___primitive_switch({ - [RayType.VERTEX]: default_pointer, - [RayType.REFERENCE]: default_pointer, - - [RayType.INITIAL]: default_pointer, - [RayType.TERMINAL]: default_pointer, - }), - - [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL), - [RayType.TERMINAL]: (initial) => boundary(RayType.TERMINAL), - - [RayType.REFERENCE]: default_pointer, - }); - - if (branches.length === 0) { - remove(pointers); // pointer, - } else { - ref.self = branches[0].as_arbitrary(); - - if (branches.length !== 1) { - pointers.push(...branches.slice(1).map(b => Ray.vertex(b.as_arbitrary()))); - } - } - } - - first = false; // TODO REMOVE - } - - if (pointers.length !== 0) - throw new PreventsImplementationBug(`${pointers.length} left`) - } - - static step = JS.Function.Impl((initial, terminal) => { - - const next_pointer = (terminal: Ray, next: JS.Arbitrary) => new Ray({ - initial: () => terminal, - terminal: next, - }); - - - const follow_direction = (terminal: Ray): Ray => next_pointer(terminal, () => terminal.follow_direction()); - - const dereference = (terminal: Ray) => next_pointer(terminal, () => terminal.dereference); - - const arbitrary_continuations = (terminal: Ray): Ray => next_pointer(terminal, () => initial.___primitive_switch({ - [RayType.INITIAL]: (initial) => Ray.directions.next(terminal), - [RayType.TERMINAL]: (initial) => Ray.directions.previous(terminal), - })); - - const boundary = (boundary: Boundary) => (terminal: Ray): Ray => terminal.___primitive_switch({ - - [RayType.VERTEX]: arbitrary_continuations, - - [boundary]: follow_direction, - [opposite(boundary)]: follow_direction, - - [RayType.REFERENCE]: dereference, - }); - - return initial.___primitive_switch({ - [RayType.VERTEX]: (initial) => dereference(terminal), - - [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL)(terminal), - [RayType.TERMINAL]: (initial) => boundary(RayType.TERMINAL)(terminal), - - [RayType.REFERENCE]: dereference, - }); - }); - step = Ray.step.as_method(this); - - // TODO; Maybe replace switch with 'zip'?, What are the practical differences? - // TODO: switch/match Should be abstracted into Ray? - ___primitive_switch = (cases: SwitchCases TResult)>): TResult => { - const _case = cases[this.type]; - - if (_case === undefined || _.isString(_case)) - throw new PreventsImplementationBug(_case ?? `Unhandled switch case; [${this.type}]`); - - return _case(this); - } - - /** - * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. - */ - // JS.AsyncGenerator - async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } - // JS.Generator - *[Symbol.iterator](): Generator { yield *this.traverse(); } - // JS.AsyncGenerator - as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); - // JS.AsyncIterator - as_async_iterator = (): AsyncIterator => this.as_async_generator(); - // JS.Iterator - as_generator = (): Generator => this[Symbol.iterator](); - // JS.AsyncIterator - as_iterator = (): Iterator => this.as_generator(); - // JS.Array - as_array = (): Ray[] => [...this]; - // JS.String - toString = (): string => this.as_string(); - as_string = (): string => this.as_array().map(ref => ref.any.js).join(','); // TODO: PROPER + export const is_orbit = JS.Function.Two( + (a, b) => a.___instance === b.___instance + ); - as_int = (): number => { throw new NotImplementedError(); } - as_number = this.as_int; - - /** - * - * TODO: - * - This needs something much smarter at some point... - */ - all = (step: JS.Implementation = Ray.directions.next): { [key: string | symbol]: Ray } & any => { - return new Proxy(this, { - - get(self: Ray, p: string | symbol, receiver: any): any { - - // TODO: Could return arbitrary structure (or in other method than .all?) - return self.___map(ref => ref.any[p], {step}); - }, - - /** - * Can't overload things like '-=' for anything but things that return numbers... ; So just apply a general function instead. - */ - set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { - for (let ref of self.___next({step})) { // TODO; This needs to either be dynamically, or just a simple shut-off for circular ones. - ref.any[p] = JS.is_function(newValue) ? newValue(ref.any[p]) : newValue; - } - - return true; - }, - - - deleteProperty(self: Ray, p: string | symbol): boolean { - throw new NotImplementedError(); - - return true; - } - // TODO: What do these other methods on Proxy do??? - }); - - } - - /** - * Move to a JavaScript object, which will handle any complexity of existing JavaScript objects, and allows one to abstract any values contained in the {vertex} to the usual JavaScript interface. - More usual to how one thinks about functions, ..., properties. - */ - get any(): { [key: string | symbol]: Ray } & any { return this.self.proxy(); } - get ___any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } - cast = (): T => { throw new NotImplementedError(); } // TODO this.proxy(); - - /** - * Used for chaining JavaScript-provided properties - * - * TODO: DOESNT FOLLOW .ANY PATTERN? - */ - o = (object: { [key: string | symbol]: any }): Ray => { - _.keys(object).forEach(key => this.proxy()[key] = object[key]); // TODO: Can be prettier, TODO: map to Ray equivalents and add to vertices.. - return this; - } - - // All these are dirty - o2 = ({ initial, vertex, terminal }: any): Ray => { - if (initial) this.initial.o(initial); - if (vertex) this.o(vertex); - if (terminal) this.terminal.o(terminal); - - return this; - } - - protected property = (property: string | symbol, _default?: any): any => this.any[property] ??= (_default ?? Ray.None()); // TODO: Can this be prettier?? - - protected _proxy: any; - protected _dirty_store: { [key: string | symbol]: object } = {} - protected proxy = (constructor?: JS.ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: - // TODO: IMPLEMENT SPLAT... {...ray.any} - return this._proxy ??= new Proxy(this, { - - get(self: Ray, p: string | symbol, receiver: any): any { - - // throw new NotImplementedError(); - return self._dirty_store[p]; - // return self.as_arbitrary(); - }, - set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { - // TODO: - // self._dirty_store[p] = JS.is_function(newValue) ? newValue(self._dirty_store[p]) : newValue; - // throw new NotImplementedError(); - self._dirty_store[p] = newValue; - - return true; - }, - - deleteProperty(self: Ray, p: string | symbol): boolean { - if (!(p in self._dirty_store)) { - return false; - } - - delete self._dirty_store[p]; - return true; - } - // TODO: What do these other methods on Proxy do??? - }) as T; - } - - /** - * - * - Don't assume we can track back any reference to this thing. Just destroy it, set everything to None. And let anything else deal with the consequences of the deletion. - * - * TODO: - * - Could lazily try to find references. - * - Implement on proxy for 'delete ray' - */ - delete = (): Ray => { - this.self.initial = Ray.None; - this.self.self = this.self.self_reference; - this.self.terminal = Ray.None; - // TODO: REMOVE THESE - this.self._proxy = undefined; - this.self._dirty_store = {}; - - // Removes the current reference to it. - this.self = this.self_reference; - - return this; - } - - //TODO USED FOR DEBUG NOW - move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { - const target_ray = func(this.self); - - const target = target_ray.as_reference().o({ - ...this._dirty_store, - position: - target_ray.any.position - ?? this.any.position - ?? Ray.POSITION_OF_DOOM - }); - console.log('move', `${this.self.label.split(' ')[0]} -> ${target.self.label.split(' ')[0]}`); - - if (memory) { - if (!target_ray.any.traversed) { - Interface.any.rays.compose(target); - target_ray.any.traversed = true; - } - } else { - Interface.any.rays = [target]; - } - - return target; - } - - static POSITION_OF_DOOM = [0, 100, 0] - - // TODO: Abstract away as compilation - render_options = (Interface: Ray): Required => { - return ({ - position: - this.any.position - ?? (this.is_none() ? Ray.POSITION_OF_DOOM : Ray.POSITION_OF_DOOM), - rotation: - this.any.rotation - ?? [0, 0, 0], - scale: - this.any.scale - ?? (this.is_none() ? 1.5 : 1.5), - color: - (Ray.is_orbit(Interface.any.selection.self, this.self) && Interface.any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) - : ( - this.any.color - ?? (this.is_none() ? 'red' : { - [RayType.VERTEX]: 'orange', - [RayType.TERMINAL]: '#FF5555', - [RayType.INITIAL]: '#5555FF', - [RayType.REFERENCE]: '#555555', - }[this.type] - ) - ) - }); + export const self_reference = JS.Function.Self( + self => self + ); } - - ___dirty_all(c: Ray[]): Ray[] { - if (c.filter(a => a.label === this.label).length !== 0) { - return c; - } - - c.push(this); - - if (this.initial.as_reference().is_some()) - this.initial.___dirty_all(c); - if (this.vertex.as_reference().is_some()) - this.vertex.___dirty_all(c); - if (this.terminal.as_reference().is_some()) - this.terminal.___dirty_all(c); - - return c; - } - - // TODO: DOESNT DO ON .SELF - debug = (c: DebugResult): DebugRay => { - if (c[this.label] !== undefined) - return c[this.label]!; - - const of = (ray: Ray): string => { - if (ray.as_reference().is_none()) return 'None'; - - ray.debug(c); - return ray.label; - } - - const obj: any = { label: this.label }; - c[this.label] = obj; - - obj.label = this.label; - obj.initial = of(this.initial); - obj.vertex = of(this.vertex); - obj.terminal = of(this.terminal); - obj.type = this.as_reference().type; - obj.is_initial = this.as_reference().is_initial(); - obj.is_vertex = this.as_reference().is_vertex(); - obj.is_terminal = this.as_reference().is_terminal(); - obj._dirty_store = this._dirty_store; - - return obj; - } - - /** - * TODO: This should be constructed at the vertex and in general unsolvable - */ - static _label: number = 0; - get label(): string { - if (this.any.label !== undefined) - return this.any.label; - - return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; - } - - push_back = (b: Ray) => this.last().compose(b); - push_front = (b: Ray) => this.first().compose(b); - - // [index: number]: Ray; - - // length: number; - // - // concat(...items: ConcatArray[]): Ray[]; - // concat(...items: (ConcatArray | Ray)[]): Ray[]; - // concat(...items: (ConcatArray | Ray)[]): Ray[] { - // return []; - // } - // - // copyWithin(target: number, start: number, end?: number): this { - // return undefined; - // } - // - // entries(): IterableIterator<[number, Ray]> { - // return undefined; - // } - // - // every(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): this is S[]; - // every(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean; - // every(predicate, thisArg?: any): any { - // } - // - // fill(value: Ray, start?: number, end?: number): this { - // return undefined; - // } - // - // filter(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S[]; - // filter(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray[]; - // filter(predicate, thisArg?: any): any { - // } - // - // find(predicate: (value: Ray, index: number, obj: Ray[]) => value is S, thisArg?: any): S | undefined; - // find(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): Ray | undefined; - // find(predicate, thisArg?: any): any { - // } - // - // findIndex(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): number { - // return 0; - // } - // - // forEach(callbackfn: (value: Ray, index: number, array: Ray[]) => void, thisArg?: any): void { - // } - // - // indexOf(searchElement: Ray, fromIndex?: number): number { - // return 0; - // } - // - // join(separator?: string): string { - // return ""; - // } - // - // keys(): IterableIterator { - // return undefined; - // } - // - // lastIndexOf(searchElement: Ray, fromIndex?: number): number { - // return 0; - // } - // - // map(callbackfn: (value: Ray, index: number, array: Ray[]) => U, thisArg?: any): U[] { - // return []; - // } - // - // pop(): Ray | undefined { - // return undefined; - // } - // - // push(...items: Ray[]): number { - // return 0; - // } - // - // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; - // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; - // reduce(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; - // reduce(callbackfn, initialValue?): any { - // } - // - // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; - // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; - // reduceRight(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; - // reduceRight(callbackfn, initialValue?): any { - // } - // - // reverse(): Ray[] { - // return []; - // } - // - // shift(): Ray | undefined { - // return undefined; - // } - // - // slice(start?: number, end?: number): Ray[] { - // return []; - // } - // - // some(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean { - // return false; - // } - // - // sort(compareFn?: (a: Ray, b: Ray) => number): this { - // return undefined; - // } - // - // splice(start: number, deleteCount?: number): Ray[]; - // splice(start: number, deleteCount: number, ...items: Ray[]): Ray[]; - // splice(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { - // return []; - // } - // - // unshift(...items: Ray[]): number { - // return 0; - // } - // - // values(): IterableIterator { - // return undefined; - // } - // - // findLast(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S | undefined; - // findLast(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray | undefined; - // findLast(predicate, thisArg?: any): any { - // } - // - // findLastIndex(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): number { - // return 0; - // } - // - // flat(depth?: D): FlatArray[] { - // return []; - // } - // - // flatMap(callback: (this: This, value: Ray, index: number, array: Ray[]) => (ReadonlyArray | U), thisArg?: This): U[] { - // return []; - // } - // - // includes(searchElement: Ray, fromIndex?: number): boolean { - // return false; - // } - // - // toReversed(): Ray[] { - // return []; - // } - // - // toSorted(compareFn?: (a: Ray, b: Ray) => number): Ray[] { - // return []; - // } - // - // toSpliced(start: number, deleteCount: number, ...items: Ray[]): Ray[]; - // toSpliced(start: number, deleteCount?: number): Ray[]; - // toSpliced(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { - // return []; - // } - // - // with(index: number, value: Ray): Ray[] { - // return []; - // } - - } -// default = (fn: () => any): any => self.match({ -// Some: (a) => a, -// None: () => fn() -// }) -// +type Ray = Rays.Instance & { + [TKey in keyof typeof Rays.Functions]: typeof Rays.Functions[TKey] extends JS.Function + ? JS.Method + : never; +} +export default Ray; +/** + * Other possibly names: "AbstractDirectionality, ..., ???" + * @alias + * @deprecated + */ +export type AbstractDirectionality = Ray; \ No newline at end of file diff --git a/src/@orbitmines/explorer/Ray2.ts b/src/@orbitmines/explorer/Ray2.ts new file mode 100644 index 0000000..04ce484 --- /dev/null +++ b/src/@orbitmines/explorer/Ray2.ts @@ -0,0 +1,1059 @@ +import _ from "lodash"; +import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; +import {InterfaceOptions} from "./OrbitMinesExplorer"; +import JS from "./JS"; + +const opposite = (boundary: Boundary): Boundary => boundary === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL; + +/** + * https://en.wikipedia.org/wiki/Homoiconicity + */ +export interface PossiblyHomoiconic> { + get self(): T; + is_reference: () => boolean + as_reference: () => T +} + +// TODO: better debug +export type DebugResult = { [label: string]: DebugRay } +export type DebugRay = { + label: string, + initial: string, + vertex: string, + terminal: string, + is_initial: boolean, + is_vertex: boolean, + is_terminal: boolean, + type: RayType, + _dirty_store: any +} + +/** + * JavaScript wrapper for a mutable value. It is important to realize that this is merely some simple JavaScript abstraction, and anything is assumed to be inherently mutable. + * + * TODO: + * - Homotopy equivalence merely as some direction/reversibility constraint on some direction, ignoring additional structure (or incorporating it into the equiv) at the vertices. (Could be loosened where certain vertex-equivalences are also part of the homotopy) + * - Induced ignorance/equivalence along arbitrary rays. + * - Usual way of thinking about vertices is what the coninuations are here - phrase that somewhjere + * + * TODO: Any javascript class, allow warpper of function names around any ray, as a possible match + * TODO: All the methods defined here should be implemented in some Ray structure at some point + * + * TODO: Maybe want a way to destroy from one end, so that if other references try to look, they won't find additional structure. - More as a javascript implementation quirck if anything? + * + * TODO: Can do some workaround overloading through properties, at least for +/- + * + * TODO: Singlke keybind for now to show/hide the ray disambiguation or 'dead edges/..'/ + * + * + * + * TODO: All methods to 'step' variant - and an intuitive way to switch between modes + * - Through better Ray.___func + * - Transform all functions on Ray to that. (Perhaps use JavaScript generators by default (more intuitively?) - Just convert using JS.Generator) + * - No assumption of halting + * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence + * + * TODO: SWITCH/MATCH + * // TODO; Maybe replace switch with 'zip'?, What are the practical differences? + * // TODO: switch/match Should be abstracted into Ray? + * + * TODO: Stylistic + * - Consistency of Arbitrary vs non-arbitrary. + * - Reorder methods in a sensible way. + * + */ +export class Ray + implements + AbstractDirectionality, + PossiblyHomoiconic, + + AsyncIterable, + Iterable + // Array + // Dict +{ + + + + protected get self_reference() { return this.as_arbitrary(); }; + + is_some = (): boolean => !this.is_none(); + + /** + * Can be used to override default dereference behavior. + * + * TODO: This should probably be configurable on a more global setting. + * + * TODO: Difference between this.self and this.self.self.as_reference is??? + */ + get dereference() { return this.self.self.as_reference(); } + + // /** + // * Moves `this.self` and `this.self.self` to a new line. + // * + // * [ |--] this.self ----- this.self.self [--|--] + // * ______ (<- initial pointer) + // */ + // as_initial = (): Ray => { + // if (this.is_none()) { + // throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); + // } + // if (this.dereference.is_none()) { + // // TODO: Need some intuition for this check + // const vertex = this.___as_vertex(); + // + // if (vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // return vertex.follow(Ray.directions.previous); + // } + // + // const [terminal_vertex, initial_vertex] = this.___as_vertices(); + // + // if (initial_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // if (terminal_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // initial_vertex.compose(terminal_vertex); + // + // // TODO BETTER DEBUG + // + // return initial_vertex.follow(Ray.directions.previous); + // } + /** + * Moves `this.self` and `this.self.self` to a new line. + * + * [ |--] this.self.self ----- this.self [--|--] + * _____ (<- terminal pointer) + */ + as_terminal = (): Ray => { + if (this.is_none()) { + throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); + } + if (this.dereference.is_none()) { + throw new PreventsImplementationBug(); + } + + const [terminal_vertex, initial_vertex] = this.___as_vertices(); + + if (initial_vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + if (terminal_vertex.type !== RayType.VERTEX) + throw new PreventsImplementationBug(); + + initial_vertex.compose(terminal_vertex); + + // TODO BETTER DEBUG + + return Ray.directions.next(terminal_vertex); + } + private ___as_vertices = (): [Ray, Ray] => { + if (!Ray.is_orbit(this.self, this.self.self.self)) + throw new PreventsImplementationBug('Is there a use-case for this? Probably not?'); //TODO + + // TODO NOTE: THE ORDER OF `this.self` first matters here. + return [this.self.___as_vertex(), this.___as_vertex()]; + } + private ___as_vertex = (): Ray => { + const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + + return this.___ignorantly_equivalent(vertex); + } + ___ignorantly_equivalent = (ref: Ray): Ray => { + ref.self.self = this.self.as_arbitrary(); + this.self.self = ref.self.as_arbitrary(); + + return ref; + } + + /** [ ] */ static None = () => new Ray({ }); + /** [--?--] */ static vertex = (value: JS.ParameterlessFunction = Ray.None) => { + /** [ ] */ const vertex = Ray.None(); + /** [-- ] */ vertex.initial = vertex.___empty_initial(); + /** [ ? ] */ vertex.vertex = value; + /** [ --] */ vertex.terminal = vertex.___empty_terminal(); + + /** [--?--] */ return vertex; + } + /** [ |-?] */ static initial = () => Ray.vertex().initial; + /** [?-| ] */ static terminal = () => Ray.vertex().terminal; + + // TODO; Temp placeholders for now - & BETTER DEBUG + ___empty_initial = () => new Ray({ vertex: Ray.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); + ___empty_terminal = () => new Ray({ vertex: Ray.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); + + /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ + /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); + + // TODO: Difference between () => this & this.as_arbitrary , relevant for lazy/modular/ignorant structures etc.. + as_arbitrary = (): JS.ParameterlessFunction => () => this; + + /** + * TODO : COMPOSE EMPTY AS FIRST ELEMENT: + * if (initial.is_none()) { + * // 'Empty' vertex from this perspective. + * + * initial.vertex = terminal.as_arbitrary(); + * console.log('first element'); + * return terminal; + * } + */ + + // TODO: Test if references hold after equivalence/composition... + + + // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? + // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? + + // TODO: Should do, one timesteap ahead, collapse one reference, and then recursively call continues_with on the vlaue at the reference, until it yields something. + + // TODO AS += through property + // TODO: Generally, return something which knows where all continuations are. + // @alias('merge, 'continues_with', 'compose') + /** + * Compose as "Equivalence at Continuations": (can usually be done in parallel - not generally) + * - `A.compose(B)` = `(A.TERMINAL).equivalent(B.INITIAL)` + * - `A.compose(B).compose(C)` = `(A.TERMINAL).equivalent(B.INITIAL) & (B.TERMINAL).equivalent(C.INITIAL)` + * + * Another interesting connection: + * - `A.compose(B).compose(C)` = `(A.equivalent(B).equivalent(C)).dereference.(MISSING ALL FUNC).compose` + * + * @see "Continuations as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence + */ + static compose = JS.Function.Impl((initial, terminal) => { + + if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) + throw new PreventsImplementationBug(); + + // ${[...initial.self.initial.as_reference().all().js]} + if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) { + throw new PreventsImplementationBug(`[${initial.type}] - [${terminal.type}] - only composing vertices for now (${initial.self.initial.any.js} -> ${terminal.self.terminal.any.js})`); + } + + Ray.directions.next(initial).equivalent(Ray.directions.previous(terminal)); + + // return ref; TODO + return terminal; + }); + compose = Ray.compose.as_method(this); + + // TODO: Cleanup + /** + * Equivalence as "Composing Vertices": "TODO: Is this right?: Equivalence at Continuations, inside a Vertex, is parallel composition, from the perspective of the usual direction defined at the Vertex (not generally parallel)" + * - `A.equivalent(B)` = `A.as_vertex().compose(B.as_vertex())` + * - `A.equivalent(B).equivalent(C)` = `A.as_vertex().compose(B.as_vertex()).compose(C.as_vertex())` + * + * An equivalence is best understood as the drawing of a single line between two things. Where those two things might have arbitrary structure around them, but we're not checking the (non-)existence of that structure. And thus: + * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. (or: Changes of an equivalence are only applied locally, which could have global effects, but this isn't necessarily obvious). + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies + */ + static equivalent = JS.Function.Impl((initial, terminal) => { + + /** + * The simplest case, is where both sides are only aware of themselves (on .vertex). The only thing we need to do is turn an Orbit, to an Orbit which repeats every 2 steps, the intermediate step being the other thing. + * + * Or in textual terms something like: + * - A single Orbit: `(A.self = A) | (B.self = B)` (i.e. A.is_none && B.is_none) + * - To: `(A.self = B) | (B.self = A)` + * + * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. + */ + const ignorant_equivalence = (): Ray => { + return initial.___ignorantly_equivalent(terminal); + } + + // 2x Ray.None -> Turn into 2 empty references, referencing each-other. + if ( + initial.dereference.is_none() && terminal.dereference.is_none() + && !(initial.type === RayType.VERTEX && terminal.type === RayType.VERTEX) + ) { + // throw new PreventsImplementationBug(`${initial.type} / ${terminal.type}`) + return ignorant_equivalence(); + } + + // Two structures, which have `ref.self = Ray.None` -> Turn into two structures which are on a line in between them. + if (initial.dereference.is_none()) { + const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + vertex.self.self = initial.self.as_arbitrary(); + initial.self.self = vertex.self.as_arbitrary(); + + // initial.equivalent(terminal); + // return terminal; + } + if (terminal.dereference.is_none()) { + const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + vertex.self.self = terminal.self.as_arbitrary(); + terminal.self.self = vertex.self.as_arbitrary(); + + // initial.equivalent(terminal.___as_vertex()); + // return terminal; + } + + if (initial.is_boundary() && initial.dereference.is_boundary()) { + throw new NotImplementedError(); + initial.as_terminal(); + //.follow(Ray.directions.previous).compose(terminal.dereference); + // return terminal; + } + + if ( + initial.dereference.type !== RayType.VERTEX + || terminal.dereference.type !== RayType.VERTEX + || initial.dereference.self === initial.self + || terminal.dereference.self === terminal.self + ) { + throw new PreventsImplementationBug(`[${initial.type}]`) + } + + if (Ray.directions.next(initial).type !== RayType.TERMINAL || Ray.directions.previous(terminal).type !== RayType.INITIAL) { + throw new NotImplementedError(); + initial.dereference.push_back(terminal.dereference); // TODO: NON-PUSH-BACK VARIANT? (Just local splits?) + return terminal; + // throw new PreventsImplementationBug(` + // [${initial.type}](${initial.follow_direction().any.js}) + // / [${initial.dereference.type}] {${[...initial.dereference.traverse()].map(ref => ref.self.follow_direction().any.js)}} + // -> ${terminal.type} (${terminal.follow_direction().any.js}) + // / [${terminal.dereference.type}]`) + } + + // if (terminal.self.any.js === 'D') + // throw new PreventsImplementationBug(); + + initial.dereference.compose(terminal.dereference); + + return terminal; + + // initial.dereference.compose() + // return terminal; + }); + equivalent = Ray.equivalent.as_method(this); + + // zip also compose??? + // [a, b, c] zip [d, e, f] zip [g, h, i] ... + // [[a,d,g],[b,e,h],[c,f,i]] + static zip = JS.Function.Impl((initial, terminal) => { + + if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) + throw new PreventsImplementationBug('TODO: Implement'); + + if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) + throw new PreventsImplementationBug('TODO: Implement'); + + throw new NotImplementedError(); + // initial.traverse() + // return new Ray({ + // + // }); + }); + zip = Ray.zip.as_method(this); + + // pop = (): Ray => { + // this.last().previous().all.terminal = (ref) => ref.___empty_terminal(); + // } + // pop = (): Ray => this.___primitive_switch({ + // [RayType.VERTEX]: () => { + // const previous_vertex = this.self.initial.follow(Ray.directions.previous); + // + // if (this.is_none()) { + // return this; // TODO; Already empty, perhaps throw + // } + // + // return previous_vertex.___primitive_switch({ + // [RayType.VERTEX]: () => { + // console.log(previous_vertex) + // // TODO: NONHACKY + // + // previous_vertex.self.terminal = new Ray({ vertex: Ray.None, initial: previous_vertex.self.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() + // return previous_vertex; + // } + // }); + // } + // }); + + /** + * Helper methods for commonly used directions + * + * TODO: Link to step-wise walk as any function - lazy, not traversing certain paths, etc.. (for last/..) + */ + static directions = { + next: (ref: Ray) => ref.self.terminal.as_reference(), + previous: (ref: Ray) => ref.self.initial.as_reference(), + none: (ref: Ray) => ref, // Note that "None" is necessarily inconsistent + } + static follow_direction = { + [RayType.INITIAL]: Ray.directions.next, + [RayType.TERMINAL]: Ray.directions.previous + } + + /** + * .next + */ + next = (step: JS.FunctionImpl = Ray.directions.next): Ray => { + if (step(this).self.self.is_none()) + return Ray.None(); + + let current = true; + for (let ray of this.traverse(step)) { + if (current) { + current = false; + continue; + } + return ray; + } + // return [...this.traverse(step)][1] ?? Ray.None(); // TODO BAD + return Ray.None(); + } + has_next = (step: JS.FunctionImpl = Ray.directions.next): boolean => this.next(step).is_some(); + // @alias('end', 'result', 'back') + last = (step: JS.FunctionImpl = Ray.directions.next): Ray => { + const next = this.next(step); + return next.is_some() ? next.last(step) : this; + } + /** + * .previous (Just .next with a `Ray.directions.previous` default) + */ + previous = (step: JS.FunctionImpl = Ray.directions.previous): Ray => this.next(step); + has_previous = (step: JS.FunctionImpl = Ray.directions.previous): boolean => this.has_next(step); + // @alias('beginning', 'front') + first = (step: JS.FunctionImpl = Ray.directions.previous): Ray => this.last(step); + + // TODO: I Don't like this name, but it needs to get across that any equivalency, or any equivalency check for that necessarily, is local. And I want more equivalences, I run more of this method. + // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. + is_vertex_equivalent = (b: Ray) => { + // TODO; in the case of a list, each individually, again, additional structure... + } + // TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? + + // TODO: Whether the thing is referenced on the vertex: do their vertices have some connection onm this direction? + is_equivalent = (b: Ray): boolean => { return false; } // TODOl: Current references assume you can't go inside vertex.. + // TODO implement .not?? + + get count(): Ray { return JS.Number(this.as_array().length); } + + // TODO; Could return the ignorant reference to both instances, or just the result., .. + + /** + * TODO: Need more control over the (non-/)lazyness of copy. + * + * - The problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. + * + * - Additionally, a copy necessarily has some non-redundancy to it: + * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy + */ + // @alias('duplicate') + copy = (): Ray => { + // return this.self.as_reference(); // Copies the reference? + throw new NotImplementedError(); + + // const copy = new Ray({ + // initial: this.self._initial().as_reference().none_or(ref => ref.copy()).as_arbitrary(), + // vertex: this.self._vertex().as_reference().none_or(ref => ref.copy()).as_arbitrary(), + // }).o({ ___dirty_copy_buffer: {} }); + // // copy._initial = () => copy.any.___dirty_copy_buffer._initial ??= this.self._initial().as_reference().copy(); + // // copy._vertex = () => copy.any.___dirty_copy_buffer._vertex ??= this.self._vertex().as_reference().copy(); + // // copy._terminal = () => copy.any.___dirty_copy_buffer._terminal ??= this.self._terminal().as_reference().copy(); + // + // + // // TODO: Doesn't copy .any + // + // return copy.as_reference(); + } + + // none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); + + // @alias('converse', 'opposite', 'swap') + get reverse(): Ray { + const copy = this;//TODO.copy(); + + // TODO: Do we do this lazy by default? Just using refs??? - Or abstract this elsewhere to decide what to do + const swap = copy.initial; + copy.initial = copy.terminal.as_arbitrary(); + copy.terminal = swap.as_arbitrary(); + // TODO: This doesn't actually work + + return copy; + } + + /** + * TODO - Better 'value' here. (Use JS.Any??) + * + * TODO: All these should accept Ray values. + * + * .size, since .length is reserved by JavaScript. + * TODO: .size could be more tensor-like, arbitrary lengths.. + */ + // @alias('length', 'of_length') + static size = (of: number, value: any = undefined): Ray => { + let ret: Ray | undefined; + let current: Ray | undefined; + // TODO: Actual good implementation: Should be lazy + for (let i = 0; i < of; i++) { + const vertex = Ray.vertex().o({js: value}).as_reference(); + + if (!ret) { + current = ret = vertex; + } else { + current = current?.compose(vertex); + } + } + + if (!ret) + return Ray.None(); + + return ret; + } + static at = (index: number, of: number, value: any = undefined): Ray => { + return Ray.size(of, value).at(index); + } + /** + * Just uses length/size for permutation. TODO: More complex permutation/enumeration implementation should follow at some point. (@see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=One%20of%20them%20could%20even%20be%20putting%20both%20our%20points%20on%20our%20selection for an example) + * + * @see "Combinatorics as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Combinatorics%20%2D%20Combinatorics%20as%20Equivalence + */ + static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( + // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) + permutation ?? 0, + // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. + permutation === undefined ? 1 : of + ) + + at = (steps: number | Ray | JS.ParameterlessFunction): Ray => { + if (!JS.is_number(steps)) + throw new NotImplementedError('Not yet implemented for Rays.'); + + // TODO: Actual good implementation - also doesn't support modular like this + const array = [...this.traverse( + steps < 0 ? Ray.directions.previous : Ray.directions.next + )]; + + steps = Math.abs(steps); + + return array.length > steps && steps >= 0 ? ( + array[steps] ?? Ray.None() // TODO FIX: Probably a JavaScript quirck with some weird numbers, just failsafe to None. + ) : Ray.None(); + } + + // export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); + + // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' + map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + // filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + get clear(): Ray { throw new NotImplementedError(); } + + // TODO: Generalize these functions to: + // + // TODO: +default, in the case of Initial/Terminal = Ray.None, to which the default sometimes is nothing. Or in the case of min/max it's 0. + + + // TODO: being called min.x needs to return the min value within that entire structure. + + // [this.vertices().x.max(), this.edges().x.max()].max() + // [this.vertices().x.min(), this.edges().x.max()].max() + // TODO: Indicies not corresponding the the directionality defined, are probably on another abstraction layer described this way. More accurately, they're directly connected, and on a separate layer with more stuff in between... + get index(): Ray { throw new NotImplementedError(); } + // TODO: Can probably generate these on the fly, or cache them automatically + min = (_default: 0): Ray => { throw new NotImplementedError(); } + max = (_default: 0): Ray => { throw new NotImplementedError(); } + + // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS + // apply = (func: Ray) => { + + // TODO: Combine into generalized [x, min/max()] - preserve terminal/initial structure + // TODO: ray#apply. + // TODO: FROM COMPOSER + /** + * const func = [min(), '', max()] + * + * const [min_x, max_x] = [ + * // Compute the min x-coordinate of the edges and vertices in the other graph. + * compose.terminal.x.min(), // min_other + * + * // Compute the max x-coordinate of the edges and vertices in this graph. + * compose.initial.x.max(), // max_self + * ] + */ + // } + + // ___compute = () + + *traverse(step: JS.FunctionImpl = Ray.directions.next): Generator { + // TODO: Also to ___func?? + + if (this.type !== RayType.VERTEX) + throw new NotImplementedError(`[${this.type}]`); + + yield *this.___next({step}); + } + + *___next({ + step = Ray.directions.next, + } = {}): Generator { + for (let current of Ray.traverse({ + initial: this.as_arbitrary(), + step + })) { + + // TODO: You can do this non-locally with a pass over the history. This way it's local, but we''ll have to find a good example of why this might not go that well. (As this would match to any empty vertices, and maybe more) + + // TODO: Could also check for none.. + const previous = current.previous(); + + if (previous.is_vertex() && !Ray.is_orbit(previous.self, current)) { + yield previous; + } + } + } + *___map(map: (vertex: Ray) => T, { + step = Ray.directions.next, + } = {}): Generator { + for (let vertex of this.___next({step})) { + yield map(vertex); + } + } + + static step_function = ( + step: JS.FunctionImpl + ): JS.Function => { + const step_from_boundary = (from: Ray, to: Ray): Ray => { + switch (to.type) { + /** + * Dereferencing is likely in many cases quickly subject to infinite stepping (similar to INITIAL -> INITIAL, TERMINAL -> TERMINAL, VERTEX -> VERTEX. (Could be that this means that there's no continuation, a self-reference defined here, or it's some mechanism of halting.) + * + * - TODO: Simple example of infinitely finding terminals, or a reference to 'nothing - infinitely'. + * - TODO: If both are references, allow deref of both? + */ + case RayType.REFERENCE: { + throw new NotImplementedError(); + } + + /** + * A possible continuation + * INITIAL/TERMINAL -> possible previous - TERMINAL.self.initial (pass to step) + * TERMINAL/INITIAL -> possible next - INITIAL.self.terminal (pass to step) + */ + case RayType.TERMINAL: { + return Ray.follow_direction[RayType.TERMINAL](to); + } + case RayType.INITIAL: { + return Ray.follow_direction[RayType.INITIAL](to); + } + + /** + * This is the most interesting case: Many possible continuations (from the perspective of a boundary (INITIAL/TERMINAL)). + * + * NOTE: + * - There are many ways of actually implementing this. This is one which ensures the checks needed to traverse arbitrary continuations is always local (with the trade-off that you can't disambiguate between structure on edges vs structure on vertices by default). Though this can be imposed with something else. (TODO) + * + * @see = TODO + */ + case RayType.VERTEX: { + // TODO: Could check if self.self is Orbit. + + /** + * Simplest check, ensure we're coming from some place which splits into many branches + * @see = TODO + */ + if (Ray.is_orbit(from.self, to.self.self)) { + // TODO: Branch to previous.next + // this.next_pointer(Ray.directions.previous), this.next_pointer(Ray.directions.next) + + throw new NotImplementedError(); + } + + /** + * This is the one which disallows structure on edges, and assumes a vertex it finds, necessarily as additional vertices we're looking for. (But we don't need to keep track of where we are like this ; TODO: Implement variant which checks back over branch.previous() to allow for this) + * @see = TODO + */ + if ( + to.dereference.is_boundary() // Whether there's a continuation defined on the vertex. + && Ray.is_orbit(to.self, to.self.self.self) + ) { + // default pointer + // const default_pointer = (): Ray[] => { + // return pointer.terminal.is_none() ? [] : [pointer]; + // } + // TODO: Split of options.step(terminal) & new Ray({ + // initial: terminal.as_arbitrary(), + // vertex: pointer.as_arbitrary(), + // terminal: () => terminal.dereference + // }) + throw new NotImplementedError(); + } + + return step(to); + } + } + } + + return JS.Function.WithMemory( + to_step => { + const to = to_step.dereference; + + throw new NotImplementedError(); + /** + * Cannot determine what to do without context of where we are. + */ + if (to.is_none()) { + return Ray.None(); + } + + const from_step = to_step.previous(); // TODO ONLY NEEDS ONE-STEP MEMORY ; Or could be implemented as two values as each step, or??? + + const from = from_step.dereference; + + switch (from.type) { + case RayType.REFERENCE: { + throw new NotImplementedError();// previous.dereference, + } + case RayType.INITIAL: + case RayType.TERMINAL: { + return step_from_boundary(from, to); + } + case RayType.VERTEX: { + return step(to); + } + } + } + ); + } + + static *traverse(options = { + initial: Ray.None, + step: Ray.directions.next, + // branch: { + // // @alias('pruning', 'mapping', 'filtering') + // prune: (branches: Ray): Ray => branches, + // // @alias('next', 'selection', 'tactic', 'strategy') + // next: (branches: Ray): Ray => branches.first(), + // } + }): Generator { + + /** + * An arbitrary Ray of (accessible) (possible) next steps to perform in traversal. + */ + // @alias('cursor(s)', 'branch(es)', 'selection(s)') + let branches: Ray = Ray.step_function(options.step).as_ray(options.initial()); // TODO; This can be used to copy? + let branch = branches; + + while (true) { + // /** + // * Branch *Pruning, Mapping, ..., Filtering* + // */ + // branches = options.branch.prune(branches); // TODO: Could hold history + // + // /** + // * Branch *Selection, Tactic, ..., Strategy* + // */ + // + // /** + // * An arbitrary Ray of (requested) next steps to perform in parallel/.../superposition (with respect to all the other branches). + // */ + // const branches_to_traverse: Ray = options.branch.next(branches); + // + // /** + // * Make copies of our traversal for each selected branch + // */ + // // TODO + // + // /** + // * Split off traversal to each branch, selecting their respective . + // */ + // + // let branch: Ray = branches_to_traverse; //TODO + + branch.self = branch.next().as_arbitrary(); + + yield branch; + + if (branch.self.is_terminal()) + break; + + // After step, if IS_TERMINAL, nothing. assume halting (!!!at prune step ?) + + // const terminal = branch.follow(); + + // branch.self = terminal; + + /** + * if (branches.length === 0) { + * remove(pointers); // pointer, + * } else { + * ref.self = branches[0].as_arbitrary(); + * + * if (branches.length !== 1) { + * pointers.push(...branches.slice(1).map(b => Ray.vertex(b.as_arbitrary()))); + * } + * } + */ + } + + // if (pointers.length !== 0) + // throw new PreventsImplementationBug(`${pointers.length} left`) + } + + + /** + * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. + */ + // JS.AsyncGenerator + async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } + // JS.Generator + *[Symbol.iterator](): Generator { yield *this.traverse(); } + // JS.AsyncGenerator + as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); + // JS.AsyncIterator + as_async_iterator = (): AsyncIterator => this.as_async_generator(); + // JS.Iterator + as_generator = (): Generator => this[Symbol.iterator](); + // JS.AsyncIterator + as_iterator = (): Iterator => this.as_generator(); + // JS.Array + as_array = (): Ray[] => [...this]; + // JS.String + toString = (): string => this.as_string(); + as_string = (): string => this.as_array().map(ref => ref.any.js).join(','); // TODO: PROPER + + as_int = (): number => { throw new NotImplementedError(); } + as_number = this.as_int; + + /** + * + * TODO: + * - This needs something much smarter at some point... + */ + all = (step: JS.FunctionImpl = Ray.directions.next): { [key: string | symbol]: Ray } & any => { + return new Proxy(this, { + + get(self: Ray, p: string | symbol, receiver: any): any { + + // TODO: Could return arbitrary structure (or in other method than .all?) + return self.___map(ref => ref.any[p], {step}); + }, + + /** + * Can't overload things like '-=' for anything but things that return numbers... ; So just apply a general function instead. + */ + set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { + for (let ref of self.___next({step})) { // TODO; This needs to either be dynamically, or just a simple shut-off for circular ones. + ref.any[p] = JS.is_function(newValue) ? newValue(ref.any[p]) : newValue; + } + + return true; + }, + + + deleteProperty(self: Ray, p: string | symbol): boolean { + throw new NotImplementedError(); + + return true; + } + // TODO: What do these other methods on Proxy do??? + }); + + } + + /** + * Move to a JavaScript object, which will handle any complexity of existing JavaScript objects, and allows one to abstract any values contained in the {vertex} to the usual JavaScript interface. - More usual to how one thinks about functions, ..., properties. + */ + get any(): { [key: string | symbol]: Ray } & any { return this.self.proxy(); } + get ___any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } + cast = (): T => { throw new NotImplementedError(); } // TODO this.proxy(); + + /** + * Used for chaining JavaScript-provided properties + * + * TODO: DOESNT FOLLOW .ANY PATTERN? + */ + o = (object: { [key: string | symbol]: any }): Ray => { + _.keys(object).forEach(key => this.proxy()[key] = object[key]); // TODO: Can be prettier, TODO: map to Ray equivalents and add to vertices.. + return this; + } + + // All these are dirty + o2 = ({ initial, vertex, terminal }: any): Ray => { + if (initial) this.initial.o(initial); + if (vertex) this.o(vertex); + if (terminal) this.terminal.o(terminal); + + return this; + } + + protected property = (property: string | symbol, _default?: any): any => this.any[property] ??= (_default ?? Ray.None()); // TODO: Can this be prettier?? + + protected _proxy: any; + protected _dirty_store: { [key: string | symbol]: object } = {} + protected proxy = (constructor?: JS.ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: + // TODO: IMPLEMENT SPLAT... {...ray.any} + return this._proxy ??= new Proxy(this, { + + get(self: Ray, p: string | symbol, receiver: any): any { + + // throw new NotImplementedError(); + return self._dirty_store[p]; + // return self.as_arbitrary(); + }, + set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { + // TODO: + // self._dirty_store[p] = JS.is_function(newValue) ? newValue(self._dirty_store[p]) : newValue; + // throw new NotImplementedError(); + self._dirty_store[p] = newValue; + + return true; + }, + + deleteProperty(self: Ray, p: string | symbol): boolean { + if (!(p in self._dirty_store)) { + return false; + } + + delete self._dirty_store[p]; + return true; + } + // TODO: What do these other methods on Proxy do??? + }) as T; + } + + /** + * + * - Don't assume we can track back any reference to this thing. Just destroy it, set everything to None. And let anything else deal with the consequences of the deletion. + * + * TODO: + * - Could lazily try to find references. + * - Implement on proxy for 'delete ray' + */ + delete = (): Ray => { + this.self.initial = Ray.None; + this.self.self = this.self.self_reference; + this.self.terminal = Ray.None; + // TODO: REMOVE THESE + this.self._proxy = undefined; + this.self._dirty_store = {}; + + // Removes the current reference to it. + this.self = this.self_reference; + + return this; + } + + //TODO USED FOR DEBUG NOW + move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { + const target_ray = func(this.self); + + const target = target_ray.as_reference().o({ + ...this._dirty_store, + position: + target_ray.any.position + ?? this.any.position + ?? Ray.POSITION_OF_DOOM + }); + console.log('move', `${this.self.label.split(' ')[0]} -> ${target.self.label.split(' ')[0]}`); + + if (memory) { + if (!target_ray.any.traversed) { + Interface.any.rays.compose(target); + target_ray.any.traversed = true; + } + } else { + Interface.any.rays = [target]; + } + + return target; + } + + static POSITION_OF_DOOM = [0, 100, 0] + + // TODO: Abstract away as compilation + render_options = (Interface: Ray): Required => { + return ({ + position: + this.any.position + ?? (this.is_none() ? Ray.POSITION_OF_DOOM : Ray.POSITION_OF_DOOM), + rotation: + this.any.rotation + ?? [0, 0, 0], + scale: + this.any.scale + ?? (this.is_none() ? 1.5 : 1.5), + color: + (Ray.is_orbit(Interface.any.selection.self, this.self) && Interface.any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) + : ( + this.any.color + ?? (this.is_none() ? 'red' : { + [RayType.VERTEX]: 'orange', + [RayType.TERMINAL]: '#FF5555', + [RayType.INITIAL]: '#5555FF', + [RayType.REFERENCE]: '#555555', + }[this.type] + ) + ) + }); + } + + ___dirty_all(c: Ray[]): Ray[] { + if (c.filter(a => a.label === this.label).length !== 0) { + return c; + } + + c.push(this); + + if (this.initial.as_reference().is_some()) + this.initial.___dirty_all(c); + if (this.vertex.as_reference().is_some()) + this.vertex.___dirty_all(c); + if (this.terminal.as_reference().is_some()) + this.terminal.___dirty_all(c); + + return c; + } + + // TODO: DOESNT DO ON .SELF + debug = (c: DebugResult): DebugRay => { + if (c[this.label] !== undefined) + return c[this.label]!; + + const of = (ray: Ray): string => { + if (ray.as_reference().is_none()) return 'None'; + + ray.debug(c); + return ray.label; + } + + const obj: any = { label: this.label }; + c[this.label] = obj; + + obj.label = this.label; + obj.initial = of(this.initial); + obj.vertex = of(this.vertex); + obj.terminal = of(this.terminal); + obj.type = this.as_reference().type; + obj.is_initial = this.as_reference().is_initial(); + obj.is_vertex = this.as_reference().is_vertex(); + obj.is_terminal = this.as_reference().is_terminal(); + obj._dirty_store = this._dirty_store; + + return obj; + } + + /** + * TODO: This should be constructed at the vertex and in general unsolvable + */ + static _label: number = 0; + get label(): string { + if (this.any.label !== undefined) + return this.any.label; + + return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; + } + + push_back = (b: Ray) => this.last().compose(b); + push_front = (b: Ray) => this.first().compose(b); +} + +// default = (fn: () => any): any => self.match({ +// Some: (a) => a, +// None: () => fn() +// }) +// + diff --git a/src/@orbitmines/explorer/Ray3.ts b/src/@orbitmines/explorer/Ray3.ts new file mode 100644 index 0000000..3e91fdc --- /dev/null +++ b/src/@orbitmines/explorer/Ray3.ts @@ -0,0 +1,181 @@ +/** + * + */ +export class Ray + // implements + // AsyncIterable, + // Iterable + // Array +{ + + /** + * JavaScript Array + */ + // [n: number]: Ray; + // + // readonly [Symbol.unscopables]: { [K in keyof any[]]?: boolean }; + // length: number; + // + // [Symbol.iterator](): IterableIterator { + // return undefined; + // } + // + // at(index: number): Ray | undefined { + // return undefined; + // } + // + // concat(...items: ConcatArray[]): Ray[]; + // concat(...items: (ConcatArray | Ray)[]): Ray[]; + // concat(...items: (ConcatArray | Ray)[]): Ray[] { + // return []; + // } + // + // copyWithin(target: number, start: number, end?: number): this { + // return undefined; + // } + // + // entries(): IterableIterator<[number, Ray]> { + // return undefined; + // } + // + // every(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): this is S[]; + // every(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean; + // every(predicate, thisArg?: any): any { + // } + // + // fill(value: Ray, start?: number, end?: number): this { + // return undefined; + // } + // + // filter(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S[]; + // filter(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray[]; + // filter(predicate, thisArg?: any): any { + // } + // + // find(predicate: (value: Ray, index: number, obj: Ray[]) => value is S, thisArg?: any): S | undefined; + // find(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // find(predicate, thisArg?: any): any { + // } + // + // findIndex(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): number { + // return 0; + // } + // + // findLast(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S | undefined; + // findLast(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // findLast(predicate, thisArg?: any): any { + // } + // + // findLastIndex(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): number { + // return 0; + // } + // + // flat(depth?: D): FlatArray[] { + // return []; + // } + // + // flatMap(callback: (this: This, value: Ray, index: number, array: Ray[]) => (ReadonlyArray | U), thisArg?: This): U[] { + // return []; + // } + // + // forEach(callbackfn: (value: Ray, index: number, array: Ray[]) => void, thisArg?: any): void { + // } + // + // includes(searchElement: Ray, fromIndex?: number): boolean { + // return false; + // } + // + // indexOf(searchElement: Ray, fromIndex?: number): number { + // return 0; + // } + // + // join(separator?: string): string { + // return ""; + // } + // + // keys(): IterableIterator { + // return undefined; + // } + // + // lastIndexOf(searchElement: Ray, fromIndex?: number): number { + // return 0; + // } + // + // map(callbackfn: (value: Ray, index: number, array: Ray[]) => U, thisArg?: any): U[] { + // return []; + // } + // + // pop(): Ray | undefined { + // return undefined; + // } + // + // push(...items: Ray[]): number { + // return 0; + // } + // + // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; + // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; + // reduce(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduce(callbackfn, initialValue?): any { + // } + // + // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; + // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; + // reduceRight(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduceRight(callbackfn, initialValue?): any { + // } + // + // reverse(): Ray[] { + // return []; + // } + // + // shift(): Ray | undefined { + // return undefined; + // } + // + // slice(start?: number, end?: number): Ray[] { + // return []; + // } + // + // some(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean { + // return false; + // } + // + // sort(compareFn?: (a: Ray, b: Ray) => number): this { + // return undefined; + // } + // + // splice(start: number, deleteCount?: number): Ray[]; + // splice(start: number, deleteCount: number, ...items: Ray[]): Ray[]; + // splice(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // return []; + // } + // + // toReversed(): Ray[] { + // return []; + // } + // + // toSorted(compareFn?: (a: Ray, b: Ray) => number): Ray[] { + // return []; + // } + // + // toSpliced(start: number, deleteCount: number, ...items: Ray[]): Ray[]; + // toSpliced(start: number, deleteCount?: number): Ray[]; + // toSpliced(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // return []; + // } + // + // unshift(...items: Ray[]): number { + // return 0; + // } + // + // values(): IterableIterator { + // return undefined; + // } + // + // with(index: number, value: Ray): Ray[] { + // return []; + // } + +} + diff --git a/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx b/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx index c846585..0ff113c 100644 --- a/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx +++ b/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx @@ -350,7 +350,7 @@ export const QuickVisualizationInterface = ({scale = 1.5}: InterfaceOptions) => // TODO Then expand these to any-dimensional ]; const isFollowing = directions.map( - ([initial, terminal]): JS.Implementation => { + ([initial, terminal]): JS.FunctionImpl => { const toInitial = initial.some(option => pressed.includes(option)); const toTerminal = terminal.some(option => pressed.includes(option)); diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index 6dd6da2..c74030c 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -33,22 +33,22 @@ export namespace Chyp { } // Vertex.in_edges = Ray.initial - get in_edges(): Ray { return this.initial; } set in_edges(ray: JS.Arbitrary) { this.initial = ray; } + get in_edges(): Ray { return this.initial; } set in_edges(ray: JS.ParameterlessFunction) { this.initial = ray; } // Vertex.out_edges = Ray.terminal - get out_edges(): Ray { return this.terminal; } set out_edges(ray: JS.Arbitrary) { this.terminal = ray; } + get out_edges(): Ray { return this.terminal; } set out_edges(ray: JS.ParameterlessFunction) { this.terminal = ray; } } export type EData = Edge; export class Edge extends Ray { // Edge.source = Ray.initial - get source(): Ray { return this.initial; } set source(ray: JS.Arbitrary) { this.initial = ray; } - get s(): Ray { return this.initial; } set s(ray: JS.Arbitrary) { this.initial = ray; } + get source(): Ray { return this.initial; } set source(ray: JS.ParameterlessFunction) { this.initial = ray; } + get s(): Ray { return this.initial; } set s(ray: JS.ParameterlessFunction) { this.initial = ray; } // Edge.targets = Ray.terminal - get target(): Ray { return this.terminal; } set target(ray: JS.Arbitrary) { this.terminal = ray; } - get t(): Ray { return this.terminal; } set t(ray: JS.Arbitrary) { this.terminal = ray; } + get target(): Ray { return this.terminal; } set target(ray: JS.ParameterlessFunction) { this.terminal = ray; } + get t(): Ray { return this.terminal; } set t(ray: JS.ParameterlessFunction) { this.terminal = ray; } } @@ -74,10 +74,10 @@ export namespace Chyp { } // Match.domain = Ray.initial - get domain(): Ray { return this.initial; } set domain(ray: JS.Arbitrary) { this.initial = ray; } + get domain(): Ray { return this.initial; } set domain(ray: JS.ParameterlessFunction) { this.initial = ray; } // Match.codomain = Ray.terminal - get codomain(): Ray { return this.terminal; } set codomain(ray: JS.Arbitrary) { this.terminal = ray; } + get codomain(): Ray { return this.terminal; } set codomain(ray: JS.ParameterlessFunction) { this.terminal = ray; } } @@ -92,10 +92,10 @@ export namespace Chyp { } // Rule.lhs = Ray.initial - get lhs(): Ray { return this.initial; } set lhs(ray: JS.Arbitrary) { this.initial = ray; } + get lhs(): Ray { return this.initial; } set lhs(ray: JS.ParameterlessFunction) { this.initial = ray; } // Rule.rhs = Ray.terminal - get rhs(): Ray { return this.terminal; } set rhs(ray: JS.Arbitrary) { this.terminal = ray; } + get rhs(): Ray { return this.terminal; } set rhs(ray: JS.ParameterlessFunction) { this.terminal = ray; } /** * TODO: We can use the same implementation to rewrite where there's not necessarily a match between initial/terminal side of a rule. @@ -142,12 +142,12 @@ export namespace Chyp { } // Graph.inputs = Ray.initial - get inputs(): Ray { return this.initial; } set inputs(ray: JS.Arbitrary) { this.initial = ray; } - set_inputs = (ray: JS.Arbitrary): Graph => { this.inputs = ray; return this; } + get inputs(): Ray { return this.initial; } set inputs(ray: JS.ParameterlessFunction) { this.initial = ray; } + set_inputs = (ray: JS.ParameterlessFunction): Graph => { this.inputs = ray; return this; } add_inputs = (ray: Ray): Graph => { this.inputs.compose(ray); return this; } // Graph.inputs = Ray.terminal - get outputs(): Ray { return this.terminal; } set outputs(ray: JS.Arbitrary) { this.terminal = ray; } - set_outputs = (ray: JS.Arbitrary): Graph => { this.outputs = ray; return this; } + get outputs(): Ray { return this.terminal; } set outputs(ray: JS.ParameterlessFunction) { this.terminal = ray; } + set_outputs = (ray: JS.ParameterlessFunction): Graph => { this.outputs = ray; return this; } add_outputs = (ray: Ray): Graph => { this.outputs.compose(ray); return this; } } diff --git a/src/@orbitmines/rays/index.ts b/src/@orbitmines/rays/index.ts new file mode 100644 index 0000000..a4addde --- /dev/null +++ b/src/@orbitmines/rays/index.ts @@ -0,0 +1,2 @@ +// import Ray from 'Ray'; +// TODO reexport as @orbitmines/rays From 0618cd54952437d677aee1df8cf0edd1c55532c4 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 22 Jan 2024 23:17:45 +0100 Subject: [PATCH 112/138] 2024/01/22 - Refactoring Ray.ts & JS.ts into something acceptable --- src/@orbitmines/explorer/Ray.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 2111a5e..6ee0512 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -84,9 +84,9 @@ export namespace Rays { } } - export const Function = < - TProperty extends keyof typeof Rays.Functions - >(property: string | symbol): (typeof Rays.Functions)[TProperty] | undefined => Rays.Functions[property as TProperty] ?? undefined; + export const Function = ( + property: string | symbol + ): (typeof Rays.Functions)[TProperty] | undefined => Rays.Functions[property as TProperty] ?? undefined; export namespace Functions { From f7c43963effca24556eb1d96aaeb7470d4e508e6 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 23 Jan 2024 16:36:45 +0100 Subject: [PATCH 113/138] 2024/01/23 - Some initial ideas of what this refactor should look like --- README.md | 8 +- src/@orbitmines/explorer/JS.ts | 140 +++++++++++++++------ src/@orbitmines/explorer/Ray.spec.ts | 6 + src/@orbitmines/explorer/Ray.ts | 175 +++++++++++++++++++-------- src/@orbitmines/explorer/Ray2.ts | 37 ------ src/@orbitmines/explorer/Ray3.ts | 4 +- 6 files changed, 244 insertions(+), 126 deletions(-) diff --git a/README.md b/README.md index 4bcb21b..c8c3f42 100644 --- a/README.md +++ b/README.md @@ -58,4 +58,10 @@ A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hype - Running tests. - ```shell npm run test -- --watchAll - ``` \ No newline at end of file + ``` + +--- + +## JavaScript Interface Examples + +- [ ] Applying a function on a Ray (vertex/initial/terminal) ; then go inside, insde can again be a vertex/initial/terminal on each vertex, apply on those. diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts index 6146ace..0083e38 100644 --- a/src/@orbitmines/explorer/JS.ts +++ b/src/@orbitmines/explorer/JS.ts @@ -16,17 +16,35 @@ namespace JS { export type FunctionImpl = (ref: T) => T; export type Recursive = (T | Recursive)[]; - export type Method = (...other: Recursive) => TResult; + export type Method = (...other: Recursive) => Ray; - export type FunctionConstructor = - Ray - | ParameterlessFunction - | Function; + // + // export type FunctionConstructor = + // Ray + // | ParameterlessFunction + // | Function; + + // export type Interface = { + // [TKey in keyof T]: T[TKey] extends JS.Function + // ? JS.Method + // : never; + // } + + // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY + + export type Enum> = { + [TKey in T[number]]: JS.Function.Instance + } + + /** + * An Enum(eration) is a (simple) Ray. + */ + export namespace Enum { + + export const Impl = >(...values: T): Enum => { + throw new NotImplementedError(); // TODO: ONE OF 4 SELECTION RAY for the case of type. + } - export type Interface = { - [TKey in keyof T]: T[TKey] extends JS.Function - ? JS.Method - : never; } /** @@ -34,51 +52,103 @@ namespace JS { * * TODO: Is there some equivalent of this in computer science??? category theory?? */ - export class Function { // TODO: Ray could extend Function + export namespace Function { - static New = (constructor: FunctionConstructor) => new Function(constructor); + /** {T} is just an example/desired use case. But it generalizes to any function. */ + export type Type = T | Function.Instance; + + export class Instance { - /** - * Implement a function from the perspective of 'this'. - */ - static Self = (impl: (self: Ray) => TResult): Function => { - return Function.New(() => { - throw new NotImplementedError(); - }); } - /** - * Implement a function from the perspective of 'this' for 'this.self'. - */ - // static Ref = (impl: (ref: Ray) => TResult): Function => JS.Function.Self(self => impl(self.as_reference())); + export namespace None { + + export const Impl = (impl: () => Ray): Function.Instance => { + return new Function.Instance(); + } - static Two = (impl: (a: Ray, b: Ray) => TResult): Function => { - return Function.New(() => { - throw new NotImplementedError(); - }); } /** - * + * Implement a function from the perspective of 'this'. */ - static CachedAfterUse = (constructor: FunctionConstructor): FunctionConstructor => { - return constructor; - } + export namespace Self { + export const Impl = (impl: (self: Ray) => Ray): Function.Instance => { + return new Function.Instance(); + } - protected constructor(constructor: FunctionConstructor) { + export const If = (impl: (self: Ray) => Ray): Function.Instance => { + return new Function.Instance(); + } - } + export type MatchCase = [ + Function.Type, + Function.Type + ]; - call = (self: Ray) => { throw new NotImplementedError(); } + export type MatchCases = [...MatchCase[], /** 'else, ... default' **/ Function.Type]; - as_method = (self: Ray): Method => { - throw new NotImplementedError(); + export const Match = (cases: MatchCases): Function.Instance => { + return new Function.Instance(); + } + } + + export namespace Two { + export const Impl = (impl: (a: Ray, b: Ray) => Ray): Function.Instance => { + return new Function.Instance(); + } } } + // export class Function { // TODO: Ray could extend Function + // + // // static New = (constructor: FunctionConstructor) => new Function(constructor); + // + // /** + // * Implement a function from the perspective of 'this'. + // */ + // static Self = (impl: (self: Ray) => Ray): Function => { + // return Function.New(() => { + // throw new NotImplementedError(); + // }); + // } + // + // /** + // * Implement a function from the perspective of 'this' for 'this.self'. + // */ + // // static Ref = (impl: (ref: Ray) => TResult): Function => JS.Function.Self(self => impl(self.as_reference())); + // + // static Two = (impl: (a: Ray, b: Ray) => Ray): Function => { + // return Function.New(() => { + // throw new NotImplementedError(); + // }); + // } + // + // /** + // * + // */ + // // static CachedAfterUse = (constructor: FunctionConstructor): FunctionConstructor => { + // // return constructor; + // // } + // + // // protected constructor(constructor: FunctionConstructor) { + // // + // // } + // + // call = (self: Ray) => { + // throw new NotImplementedError(); + // } + // + // as_method = (self: Ray): Method => { + // throw new NotImplementedError(); + // } + // + // } /** * JavaScript runtime type checks + * + * TODO: Copy from lodash */ export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); export const is_number = (_object: any): _object is number => _.isNumber(_object); diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 846e89b..3ca79d4 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -9,6 +9,12 @@ describe("Ray", () => { expect(b.is_orbit(b)).toBe(true); expect(a.is_orbit(b)).toBe(false); }); + test(".dereference", () => { + const a = Rays.New(); + const b = Rays.New(); + + expect(a.terminal()).toBe(true); + }); // test("[A, B, C].copy", () => { // const A = Ray.vertex().o({ js: 'A' }).as_reference().o({ js: 'A.#' }); diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 6ee0512..d9e2fb4 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -4,23 +4,17 @@ import {NotImplementedError} from "./errors/errors"; export namespace Rays { export type Constructor = { - initial: JS.FunctionConstructor, - vertex: JS.FunctionConstructor, - terminal: JS.FunctionConstructor, + initial?: JS.FunctionConstructor, + self?: JS.FunctionConstructor, + terminal?: JS.FunctionConstructor, } /** * TODO: Shouldn't classify these? - * TODO: Incorporate into Ray? */ - export enum Type { - REFERENCE = '(REFERENCE: [ | ])', - INITIAL = '(INITIAL: [ |-?]', - TERMINAL = '(TERMINAL: [?-| ])', - VERTEX = '(VERTEX: [--|--])', - } + export const Type = JS.Enum.Impl('REFERENCE', 'INITIAL', 'TERMINAL', 'VERTEX'); - export type Boundary = Type.INITIAL | Type.TERMINAL; + // export const Boundary = { INITIAL: Type.INITIAL, TERMINAL: Type.TERMINAL }; TODO: LIST O export const New = (constructor?: Rays.Constructor): Ray => Rays.Instance.New(constructor).proxy; @@ -35,33 +29,28 @@ export namespace Rays { protected readonly _proxy: Ray; - /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ get initial(): Ray { return this._initial.call(this.proxy); } set initial(initial: JS.FunctionConstructor) { this._initial = JS.Function.New(initial); } protected _initial: JS.Function; - /** An arbitrary Ray, defining what our current position is equivalent to. */ get self(): Ray { return this._self.call(this.proxy); } set self(self: JS.FunctionConstructor) { this._self = JS.Function.New(self); } protected _self: JS.Function; - /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ get terminal(): Ray { return this._terminal.call(this.proxy); } set terminal(terminal: JS.FunctionConstructor) { this._terminal = JS.Function.New(terminal); } protected _terminal: JS.Function; get proxy(): Ray { return this._proxy; } - protected constructor({ initial, vertex, terminal }: Partial = {}) { - this._proxy = new Proxy(this as unknown as Ray, Rays.ProxyHandler); + protected constructor({ initial, self, terminal }: Rays.Constructor = {}) { + this._proxy = new Proxy(this, Rays.ProxyHandler) as unknown as Ray; this._initial = JS.Function.New(initial ?? Rays.None); - this._self = JS.Function.New(vertex ?? this.proxy); + this._self = JS.Function.New(self ?? this.proxy); this._terminal = JS.Function.New(terminal ?? Rays.None); } - /** - * Used to jump out of the proxy. - */ + /** Used to jump out of the proxy. */ get ___instance(): Instance { return this; } } - export const ProxyHandler: ProxyHandler = { + export const ProxyHandler: ProxyHandler = { get: (self: Instance, property: string | symbol, proxy: Ray): any => { - /** Use any field defined on {Rays.Instance} first. */ - const field = (self as any)[property]; - if (field) { return field; } + // /** Use any field defined on {Rays.Instance} first. */ + // const field = (self as any)[property]; + if (property === '___instance') { return self.___instance; } /** Otherwise, switch to functions defined on {Rays.Functions} */ const func = Rays.Function(property); @@ -90,28 +79,28 @@ export namespace Rays { export namespace Functions { - /** [ |-?] */ export const is_initial = JS.Function.Self( - self => self.is_some() && self.initial.is_none() + /** [ |-?] */ export const is_initial = JS.Function.Self.Impl( + self => self.is_some().and(self.initial().is_none()) ); - /** [--|--] */ export const is_vertex = JS.Function.Self( - self => !self.is_initial() && !self.is_terminal() + /** [--|--] */ export const is_vertex = JS.Function.Self.Impl( + self => self.is_initial().not().and(self.is_terminal().not()) ); - /** [?-| ] */ export const is_terminal = JS.Function.Self( - self => self.is_some() && self.terminal.is_none() + /** [?-| ] */ export const is_terminal = JS.Function.Self.Impl( + self => self.is_some().and(self.terminal().is_none()) ); - /** [ | ] */ export const is_reference = JS.Function.Self( - self => self.is_initial() && self.is_terminal() + /** [ | ] */ export const is_reference = JS.Function.Self.Impl( + self => self.is_initial().and(self.is_terminal()) ); - /** [?-| ] or [ |-?] */ export const is_boundary = JS.Function.Self( - self => !self.is_reference() && (self.is_initial() || self.is_terminal()) + /** [?-| ] or [ |-?] */ export const is_boundary = JS.Function.Self.Impl( + self => ( self.is_reference().not() ).and( self.is_initial().or(self.is_terminal()) ) ); - export const type = JS.Function.Self(self => { - /** [ | ] */ if (self.is_reference()) return Rays.Type.REFERENCE; - /** [ |-?] */ if (self.is_initial()) return Rays.Type.INITIAL; - /** [?-| ] */ if (self.is_terminal()) return Rays.Type.TERMINAL; - /** [--|--] */ return Rays.Type.VERTEX; - }); + export const type = JS.Function.Self.Match([ + /** [ | ] */ [is_reference, Rays.Type.REFERENCE], + /** [ |-?] */ [is_initial, Rays.Type.INITIAL], + /** [?-| ] */ [is_terminal, Rays.Type.TERMINAL], + /** [--|--] */ Rays.Type.VERTEX + ]); /** * This is basically what breaks the recursive structure. @@ -124,13 +113,13 @@ export namespace Rays { * * As a way of saying/.../assuming: I only 'infinitely' assume it's only this structure, "it seems to halt here". Note that this is necessarily an assumption. No guarantee of this can be made. This is necessarily an equivalence, ..., ignorance. * - * See more: https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. */ - export const is_none = JS.Function.Self( - self => self.is_orbit(self.self) + export const is_none = JS.Function.Self.Impl( + self => self.is_orbit(self.dereference()) ); - export const is_some = JS.Function.Self( - self => !self.is_none() + export const is_some = JS.Function.Self.Impl( + self => self.is_none().not() ); /** @@ -138,19 +127,105 @@ export namespace Rays { * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. */ - export const is_orbit = JS.Function.Two( + export const is_orbit = JS.Function.Two.Impl( (a, b) => a.___instance === b.___instance ); - export const self_reference = JS.Function.Self( + export const self_reference = JS.Function.Self.Impl( self => self ); + + /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ + export const terminal = JS.Function.Self.Impl( + self => self.___instance.terminal // TODO .as_reference? Basically, Ray.directions + ); + /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ + export const initial = JS.Function.Self.Impl( + self => self.___instance.initial // TODO .as_reference? + ); + + /** + * An arbitrary Ray, defining what our current position is equivalent to. + * + * Moving to the intersecting Ray at `.self` - as a way of going an abstraction layer (lower), and asking what's inside. + */ + export const dereference = JS.Function.Self.Impl( + self => self.___instance.self // TODO .as_reference? + ); + /** + * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. + */ + export const reference = JS.Function.Self.Impl( + self => Rays.New({ self: self }) + ); + + export const compose = JS.Function.Two.Impl( + (a, b) => { + throw new NotImplementedError(); + return b; + }); + export const equivalent = JS.Function.Two.Impl( + (a, b) => { + // TODO: = COMPOSE + throw new NotImplementedError(); + return b; + }); + + export const is_equivalent = JS.Function.Two.Impl( + (a, b) => { + // TODO: = COMPOSE + throw new NotImplementedError(); + return true; + }); + + export const next = JS.Function.Self.Impl((self) => { + throw new NotImplementedError(); + return self; + }); + export const has_next = JS.Function.Self.Impl((self) => { + throw new NotImplementedError(); + return true; + }); + // @alias('end', 'result', 'back', 'output') + export const last = JS.Function.Self.Impl((self) => { + throw new NotImplementedError(); + return self; + }); + export const first = JS.Function.Self.Impl((self) => { + throw new NotImplementedError(); + return self; + }); + + // @alias('not', 'reverse', 'swap', 'converse') + export const not = JS.Function.Self.Impl((self) => { + throw new NotImplementedError(); + return self; + }); + export const and = JS.Function.Two.Impl((a, b) => { + throw new NotImplementedError(); + return self; + }); + export const or = JS.Function.Two.Impl((a, b) => { + throw new NotImplementedError(); + return self; + }); + + + // @alias(`push_{last.alias}`) + export const push_back = JS.Function.Two.Impl( + (a, b) => a.last().compose(b) + ); + // @alias(`push_{first.alias}`) + export const push_front = JS.Function.Two.Impl( + (a, b) => b.compose(a.first()) + ); + } } -type Ray = Rays.Instance & { - [TKey in keyof typeof Rays.Functions]: typeof Rays.Functions[TKey] extends JS.Function - ? JS.Method +type Ray = Pick & { + [TKey in keyof typeof Rays.Functions]: typeof Rays.Functions[TKey] extends JS.Function.Instance + ? JS.Method : never; } export default Ray; diff --git a/src/@orbitmines/explorer/Ray2.ts b/src/@orbitmines/explorer/Ray2.ts index 04ce484..4270f21 100644 --- a/src/@orbitmines/explorer/Ray2.ts +++ b/src/@orbitmines/explorer/Ray2.ts @@ -72,22 +72,6 @@ export class Ray // Array // Dict { - - - - protected get self_reference() { return this.as_arbitrary(); }; - - is_some = (): boolean => !this.is_none(); - - /** - * Can be used to override default dereference behavior. - * - * TODO: This should probably be configurable on a more global setting. - * - * TODO: Difference between this.self and this.self.self.as_reference is??? - */ - get dereference() { return this.self.self.as_reference(); } - // /** // * Moves `this.self` and `this.self.self` to a new line. // * @@ -183,12 +167,6 @@ export class Ray ___empty_initial = () => new Ray({ vertex: Ray.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); ___empty_terminal = () => new Ray({ vertex: Ray.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); - /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ - /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); - - // TODO: Difference between () => this & this.as_arbitrary , relevant for lazy/modular/ignorant structures etc.. - as_arbitrary = (): JS.ParameterlessFunction => () => this; - /** * TODO : COMPOSE EMPTY AS FIRST ELEMENT: * if (initial.is_none()) { @@ -372,16 +350,6 @@ export class Ray // } // }); - /** - * Helper methods for commonly used directions - * - * TODO: Link to step-wise walk as any function - lazy, not traversing certain paths, etc.. (for last/..) - */ - static directions = { - next: (ref: Ray) => ref.self.terminal.as_reference(), - previous: (ref: Ray) => ref.self.initial.as_reference(), - none: (ref: Ray) => ref, // Note that "None" is necessarily inconsistent - } static follow_direction = { [RayType.INITIAL]: Ray.directions.next, [RayType.TERMINAL]: Ray.directions.previous @@ -427,8 +395,6 @@ export class Ray // TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? // TODO: Whether the thing is referenced on the vertex: do their vertices have some connection onm this direction? - is_equivalent = (b: Ray): boolean => { return false; } // TODOl: Current references assume you can't go inside vertex.. - // TODO implement .not?? get count(): Ray { return JS.Number(this.as_array().length); } @@ -463,7 +429,6 @@ export class Ray // none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); - // @alias('converse', 'opposite', 'swap') get reverse(): Ray { const copy = this;//TODO.copy(); @@ -1047,8 +1012,6 @@ export class Ray return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; } - push_back = (b: Ray) => this.last().compose(b); - push_front = (b: Ray) => this.first().compose(b); } // default = (fn: () => any): any => self.match({ diff --git a/src/@orbitmines/explorer/Ray3.ts b/src/@orbitmines/explorer/Ray3.ts index 3e91fdc..2ef81c8 100644 --- a/src/@orbitmines/explorer/Ray3.ts +++ b/src/@orbitmines/explorer/Ray3.ts @@ -1,6 +1,4 @@ -/** - * - */ + export class Ray // implements // AsyncIterable, From e212a7fea7749f8141115df0b2af9ce836481ba7 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 23 Jan 2024 20:49:18 +0100 Subject: [PATCH 114/138] 2024/01/23 - Some initial ideas of what this refactor should look like --- src/@orbitmines/explorer/JS.ts | 63 ++++++++++++------ src/@orbitmines/explorer/Ray.spec.ts | 19 +++--- src/@orbitmines/explorer/Ray.ts | 76 +++++++++++++--------- src/@orbitmines/explorer/Ray2.ts | 48 +------------- src/@orbitmines/external/chyp/Chyp.spec.ts | 46 +++++++------ 5 files changed, 123 insertions(+), 129 deletions(-) diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts index 0083e38..51d2b47 100644 --- a/src/@orbitmines/explorer/JS.ts +++ b/src/@orbitmines/explorer/JS.ts @@ -42,7 +42,12 @@ namespace JS { export namespace Enum { export const Impl = >(...values: T): Enum => { - throw new NotImplementedError(); // TODO: ONE OF 4 SELECTION RAY for the case of type. + return Object.fromEntries(values.map(value => + [value, JS.Function.None.Impl((): Ray => { + throw new NotImplementedError(); // TODO + })] + )) as Enum; + // TODO: ONE OF 4 SELECTION RAY for the case of type. } } @@ -57,14 +62,44 @@ namespace JS { /** {T} is just an example/desired use case. But it generalizes to any function. */ export type Type = T | Function.Instance; + /** From which perspective the Function is implemented. */ + enum Perspective { + None, + Self, + // Ref, + } + export class Instance { + readonly perspective: Perspective; + readonly impl: (...params: Ray[]) => Ray; + + constructor({ perspective, impl }: Pick) { + this.perspective = perspective; + this.impl = impl; + } + + as_method = (self: Ray): Method => { + return () => { throw new NotImplementedError(); } + // throw new NotImplementedError(); + } + + /** + * TODO + * - Compose empty as first element? Disregard none to first elemn? Or not?? + * + * TODO; Impl + * - Generally, return something which knows where all continuations are. + * TODO: Testing + * - Test if references hold after equivalence/composition... + * + */ } export namespace None { export const Impl = (impl: () => Ray): Function.Instance => { - return new Function.Instance(); + return new Function.Instance({ perspective: Perspective.None, impl }); } } @@ -74,11 +109,15 @@ namespace JS { */ export namespace Self { export const Impl = (impl: (self: Ray) => Ray): Function.Instance => { - return new Function.Instance(); + return new Function.Instance({ perspective: Perspective.Self, impl }); + } + + export const Two = (impl: (a: Ray, b: Ray) => Ray): Function.Instance => { + return new Function.Instance({ perspective: Perspective.Self, impl }); // TODO: Good way to deal with arity } export const If = (impl: (self: Ray) => Ray): Function.Instance => { - return new Function.Instance(); + return Impl(impl); // TODO: GENERIC collapse to boolean implemented and overridable } export type MatchCase = [ @@ -89,13 +128,7 @@ namespace JS { export type MatchCases = [...MatchCase[], /** 'else, ... default' **/ Function.Type]; export const Match = (cases: MatchCases): Function.Instance => { - return new Function.Instance(); - } - } - - export namespace Two { - export const Impl = (impl: (a: Ray, b: Ray) => Ray): Function.Instance => { - return new Function.Instance(); + return Impl(self => self); // TODO } } @@ -104,14 +137,6 @@ namespace JS { // // // static New = (constructor: FunctionConstructor) => new Function(constructor); // - // /** - // * Implement a function from the perspective of 'this'. - // */ - // static Self = (impl: (self: Ray) => Ray): Function => { - // return Function.New(() => { - // throw new NotImplementedError(); - // }); - // } // // /** // * Implement a function from the perspective of 'this' for 'this.self'. diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 3ca79d4..58c011f 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -1,19 +1,18 @@ import Ray, {Rays} from "./Ray"; describe("Ray", () => { - test(".is_orbit", () => { - const a = Rays.New(); - const b = Rays.New(); - - expect(a.is_orbit(a)).toBe(true); - expect(b.is_orbit(b)).toBe(true); - expect(a.is_orbit(b)).toBe(false); - }); + // test(".is_orbit", () => { + // const a = Rays.New(); + // const b = Rays.New(); + // + // expect(a.is_orbit(a)).toBe(true); + // expect(b.is_orbit(b)).toBe(true); + // expect(a.is_orbit(b)).toBe(false); + // }); test(".dereference", () => { const a = Rays.New(); - const b = Rays.New(); - expect(a.terminal()).toBe(true); + expect(a.dereference()).toBe(true); }); // test("[A, B, C].copy", () => { diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index d9e2fb4..4b3f696 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -4,9 +4,9 @@ import {NotImplementedError} from "./errors/errors"; export namespace Rays { export type Constructor = { - initial?: JS.FunctionConstructor, - self?: JS.FunctionConstructor, - terminal?: JS.FunctionConstructor, + // initial?: JS.FunctionConstructor, + // self?: JS.FunctionConstructor, + // terminal?: JS.FunctionConstructor, } /** @@ -21,7 +21,7 @@ export namespace Rays { /** * An uninitialized empty Ray, which caches itself once initialized. */ - export const None: JS.FunctionConstructor = JS.Function.CachedAfterUse(Rays.New); + // export const None: JS.FunctionConstructor = JS.Function.CachedAfterUse(Rays.New); export class Instance { @@ -29,23 +29,26 @@ export namespace Rays { protected readonly _proxy: Ray; - get initial(): Ray { return this._initial.call(this.proxy); } set initial(initial: JS.FunctionConstructor) { this._initial = JS.Function.New(initial); } protected _initial: JS.Function; - get self(): Ray { return this._self.call(this.proxy); } set self(self: JS.FunctionConstructor) { this._self = JS.Function.New(self); } protected _self: JS.Function; - get terminal(): Ray { return this._terminal.call(this.proxy); } set terminal(terminal: JS.FunctionConstructor) { this._terminal = JS.Function.New(terminal); } protected _terminal: JS.Function; + // get initial(): Ray { return this._initial.call(this.proxy); } set initial(initial: JS.FunctionConstructor) { this._initial = JS.Function.New(initial); } protected _initial: JS.Function; + // get self(): Ray { return this._self.call(this.proxy); } set self(self: JS.FunctionConstructor) { this._self = JS.Function.New(self); } protected _self: JS.Function; + // get terminal(): Ray { return this._terminal.call(this.proxy); } set terminal(terminal: JS.FunctionConstructor) { this._terminal = JS.Function.New(terminal); } protected _terminal: JS.Function; get proxy(): Ray { return this._proxy; } - protected constructor({ initial, self, terminal }: Rays.Constructor = {}) { + protected constructor({ + // initial, self, terminal + }: Rays.Constructor = {}) { this._proxy = new Proxy(this, Rays.ProxyHandler) as unknown as Ray; - this._initial = JS.Function.New(initial ?? Rays.None); - this._self = JS.Function.New(self ?? this.proxy); - this._terminal = JS.Function.New(terminal ?? Rays.None); + // this._initial = JS.Function.New(initial ?? Rays.None); + // this._self = JS.Function.New(self ?? this.proxy); + // this._terminal = JS.Function.New(terminal ?? Rays.None); } /** Used to jump out of the proxy. */ get ___instance(): Instance { return this; } } + // TODO AS += through property, anything possible export const ProxyHandler: ProxyHandler = { get: (self: Instance, property: string | symbol, proxy: Ray): any => { // /** Use any field defined on {Rays.Instance} first. */ @@ -80,19 +83,19 @@ export namespace Rays { export namespace Functions { /** [ |-?] */ export const is_initial = JS.Function.Self.Impl( - self => self.is_some().and(self.initial().is_none()) + self => self.initial().is_none() ); /** [--|--] */ export const is_vertex = JS.Function.Self.Impl( - self => self.is_initial().not().and(self.is_terminal().not()) + self => self.is_initial().nor(self.is_terminal()) ); /** [?-| ] */ export const is_terminal = JS.Function.Self.Impl( - self => self.is_some().and(self.terminal().is_none()) + self => self.terminal().is_none() ); /** [ | ] */ export const is_reference = JS.Function.Self.Impl( self => self.is_initial().and(self.is_terminal()) ); /** [?-| ] or [ |-?] */ export const is_boundary = JS.Function.Self.Impl( - self => ( self.is_reference().not() ).and( self.is_initial().or(self.is_terminal()) ) + self => self.is_initial().xor(self.is_terminal()) ); export const type = JS.Function.Self.Match([ @@ -127,7 +130,7 @@ export namespace Rays { * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. */ - export const is_orbit = JS.Function.Two.Impl( + export const is_orbit = JS.Function.Self.Two( (a, b) => a.___instance === b.___instance ); @@ -143,7 +146,6 @@ export namespace Rays { export const initial = JS.Function.Self.Impl( self => self.___instance.initial // TODO .as_reference? ); - /** * An arbitrary Ray, defining what our current position is equivalent to. * @@ -159,19 +161,29 @@ export namespace Rays { self => Rays.New({ self: self }) ); - export const compose = JS.Function.Two.Impl( - (a, b) => { - throw new NotImplementedError(); - return b; - }); - export const equivalent = JS.Function.Two.Impl( + /** + * @see "Continuations as Equivalence (can often be done in parallel - not generally)": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence + */ + // @alias('merge, 'continues_with', 'compose') + export const compose = JS.Function.Self.Two( + (a, b) => a.terminal().equivalent(b.initial()) + ); + + /** + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies + */ + export const equivalent = JS.Function.Self.Two( (a, b) => { // TODO: = COMPOSE throw new NotImplementedError(); - return b; + + // TODO: This is close but not quite, use the shifting thing I wrote down a few days ago: (And then use something to break the self-reference) - Either on this side. compose, or outside the definitions + // This one harder to do in parallel? + return a.dereference().compose(b.dereference()); }); - export const is_equivalent = JS.Function.Two.Impl( + export const is_equivalent = JS.Function.Self.Two( (a, b) => { // TODO: = COMPOSE throw new NotImplementedError(); @@ -201,22 +213,28 @@ export namespace Rays { throw new NotImplementedError(); return self; }); - export const and = JS.Function.Two.Impl((a, b) => { + export const and = JS.Function.Self.Two((a, b) => { + throw new NotImplementedError(); + return self; + }); + export const or = JS.Function.Self.Two((a, b) => { throw new NotImplementedError(); return self; }); - export const or = JS.Function.Two.Impl((a, b) => { + export const xor = JS.Function.Self.Two((a, b) => { throw new NotImplementedError(); return self; }); + export const nand = JS.Function.Self.Two((a, b) => a.and(b).not()); + export const nor = JS.Function.Self.Two((a, b) => a.or(b).not()); // @alias(`push_{last.alias}`) - export const push_back = JS.Function.Two.Impl( + export const push_back = JS.Function.Self.Two( (a, b) => a.last().compose(b) ); // @alias(`push_{first.alias}`) - export const push_front = JS.Function.Two.Impl( + export const push_front = JS.Function.Self.Two( (a, b) => b.compose(a.first()) ); diff --git a/src/@orbitmines/explorer/Ray2.ts b/src/@orbitmines/explorer/Ray2.ts index 4270f21..09085ed 100644 --- a/src/@orbitmines/explorer/Ray2.ts +++ b/src/@orbitmines/explorer/Ray2.ts @@ -167,65 +167,19 @@ export class Ray ___empty_initial = () => new Ray({ vertex: Ray.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); ___empty_terminal = () => new Ray({ vertex: Ray.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); - /** - * TODO : COMPOSE EMPTY AS FIRST ELEMENT: - * if (initial.is_none()) { - * // 'Empty' vertex from this perspective. - * - * initial.vertex = terminal.as_arbitrary(); - * console.log('first element'); - * return terminal; - * } - */ - // TODO: Test if references hold after equivalence/composition... // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? - // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? - - // TODO: Should do, one timesteap ahead, collapse one reference, and then recursively call continues_with on the vlaue at the reference, until it yields something. - - // TODO AS += through property - // TODO: Generally, return something which knows where all continuations are. - // @alias('merge, 'continues_with', 'compose') - /** - * Compose as "Equivalence at Continuations": (can usually be done in parallel - not generally) - * - `A.compose(B)` = `(A.TERMINAL).equivalent(B.INITIAL)` - * - `A.compose(B).compose(C)` = `(A.TERMINAL).equivalent(B.INITIAL) & (B.TERMINAL).equivalent(C.INITIAL)` - * - * Another interesting connection: - * - `A.compose(B).compose(C)` = `(A.equivalent(B).equivalent(C)).dereference.(MISSING ALL FUNC).compose` - * - * @see "Continuations as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence - */ - static compose = JS.Function.Impl((initial, terminal) => { - if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) - throw new PreventsImplementationBug(); - - // ${[...initial.self.initial.as_reference().all().js]} - if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) { - throw new PreventsImplementationBug(`[${initial.type}] - [${terminal.type}] - only composing vertices for now (${initial.self.initial.any.js} -> ${terminal.self.terminal.any.js})`); - } - - Ray.directions.next(initial).equivalent(Ray.directions.previous(terminal)); - // return ref; TODO - return terminal; - }); - compose = Ray.compose.as_method(this); - - // TODO: Cleanup /** * Equivalence as "Composing Vertices": "TODO: Is this right?: Equivalence at Continuations, inside a Vertex, is parallel composition, from the perspective of the usual direction defined at the Vertex (not generally parallel)" - * - `A.equivalent(B)` = `A.as_vertex().compose(B.as_vertex())` - * - `A.equivalent(B).equivalent(C)` = `A.as_vertex().compose(B.as_vertex()).compose(C.as_vertex())` * * An equivalence is best understood as the drawing of a single line between two things. Where those two things might have arbitrary structure around them, but we're not checking the (non-)existence of that structure. And thus: * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. (or: Changes of an equivalence are only applied locally, which could have global effects, but this isn't necessarily obvious). * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies + * */ static equivalent = JS.Function.Impl((initial, terminal) => { diff --git a/src/@orbitmines/external/chyp/Chyp.spec.ts b/src/@orbitmines/external/chyp/Chyp.spec.ts index 4902ac4..2f1cff2 100644 --- a/src/@orbitmines/external/chyp/Chyp.spec.ts +++ b/src/@orbitmines/external/chyp/Chyp.spec.ts @@ -1,30 +1,28 @@ -import {Ray} from "../../explorer/Ray"; -import {Chyp} from "./Chyp"; describe("Chyp", () => { describe(".Graph", () => { - test(".set_inputs", () => { - const graph = Chyp.Graph.new() - .set_inputs(Ray.vertex().o({ js: 'B' }).as_arbitrary()) - .set_inputs(Ray.vertex().o({ js: 'A' }).as_arbitrary()); - - expect(graph.inputs.as_reference().any.js).toBe('A'); - expect(graph.initial.as_reference().any.js).toBe('A'); - expect(graph.inputs.as_reference().any.js).toBe(graph.initial.as_reference().any.js); - expect(graph.inputs).toBe(graph.initial); - }); - - }); - describe(".Rule", () => { - test(".name", () => { - let rule = Chyp.Rule.new(); - rule.name = 'test'; - - expect(rule.name).toBe('test'); - expect(rule.reverse.any.name).toBe('-test'); - // expect(rule.reverse.reverse.any.name).toBe('test'); - - }); + // test(".set_inputs", () => { + // const graph = Chyp.Graph.new() + // .set_inputs(Ray.vertex().o({ js: 'B' }).as_arbitrary()) + // .set_inputs(Ray.vertex().o({ js: 'A' }).as_arbitrary()); + // + // expect(graph.inputs.as_reference().any.js).toBe('A'); + // expect(graph.initial.as_reference().any.js).toBe('A'); + // expect(graph.inputs.as_reference().any.js).toBe(graph.initial.as_reference().any.js); + // expect(graph.inputs).toBe(graph.initial); + // }); + // }); + // describe(".Rule", () => { + // test(".name", () => { + // let rule = Chyp.Rule.new(); + // rule.name = 'test'; + // + // expect(rule.name).toBe('test'); + // expect(rule.reverse.any.name).toBe('-test'); + // // expect(rule.reverse.reverse.any.name).toBe('test'); + // + // }); + // }); }); From 0a9bfc40dff87ab15ba24d3a7c3df4d2a7795702 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 23 Jan 2024 21:19:56 +0100 Subject: [PATCH 115/138] 2024/01/23 - Some initial ideas of what this refactor should look like --- src/@orbitmines/explorer/Ray.ts | 11 +++++++++-- src/@orbitmines/explorer/Ray2.ts | 5 ----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 4b3f696..0b6b1bb 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -151,9 +151,12 @@ export namespace Rays { * * Moving to the intersecting Ray at `.self` - as a way of going an abstraction layer (lower), and asking what's inside. */ + // @alias('dereference', 'self') export const dereference = JS.Function.Self.Impl( self => self.___instance.self // TODO .as_reference? ); + export const self = dereference; + /** * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. */ @@ -170,17 +173,21 @@ export namespace Rays { ); /** + * Equivalence as "Composition of Rays." + * + * NOTE: + * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. And it is expensive work to edge towards global coherence. + * - Though changes are only applied locally, their effects can be global (Take for instance, the example of adding to one Ray, which changes the perspective of everything connected to that Ray if they were to traverse the connection). * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies */ export const equivalent = JS.Function.Self.Two( (a, b) => { - // TODO: = COMPOSE throw new NotImplementedError(); // TODO: This is close but not quite, use the shifting thing I wrote down a few days ago: (And then use something to break the self-reference) - Either on this side. compose, or outside the definitions // This one harder to do in parallel? - return a.dereference().compose(b.dereference()); + return a.self().compose(b.self()); }); export const is_equivalent = JS.Function.Self.Two( diff --git a/src/@orbitmines/explorer/Ray2.ts b/src/@orbitmines/explorer/Ray2.ts index 09085ed..3e1a452 100644 --- a/src/@orbitmines/explorer/Ray2.ts +++ b/src/@orbitmines/explorer/Ray2.ts @@ -174,11 +174,6 @@ export class Ray /** - * Equivalence as "Composing Vertices": "TODO: Is this right?: Equivalence at Continuations, inside a Vertex, is parallel composition, from the perspective of the usual direction defined at the Vertex (not generally parallel)" - * - * An equivalence is best understood as the drawing of a single line between two things. Where those two things might have arbitrary structure around them, but we're not checking the (non-)existence of that structure. And thus: - * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. (or: Changes of an equivalence are only applied locally, which could have global effects, but this isn't necessarily obvious). - * * */ static equivalent = JS.Function.Impl((initial, terminal) => { From e2923792912231d13af70ec81899d4f9414fb826 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 23 Jan 2024 21:57:27 +0100 Subject: [PATCH 116/138] 2024/01/23 - Separate things actually necessary to get traversal working --- src/@orbitmines/explorer/JS.ts | 12 + .../REFACTOR_AFTER_WORKING_TRAVERSE.md | 444 ++++++++++++++++++ src/@orbitmines/explorer/REFACTOR_RENDER.md | 59 +++ src/@orbitmines/explorer/Ray2.ts | 351 +------------- src/@orbitmines/explorer/Ray3.ts | 179 ------- 5 files changed, 517 insertions(+), 528 deletions(-) create mode 100644 src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md create mode 100644 src/@orbitmines/explorer/REFACTOR_RENDER.md delete mode 100644 src/@orbitmines/explorer/Ray3.ts diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts index 51d2b47..9f12d77 100644 --- a/src/@orbitmines/explorer/JS.ts +++ b/src/@orbitmines/explorer/JS.ts @@ -90,9 +90,17 @@ namespace JS { * * TODO; Impl * - Generally, return something which knows where all continuations are. + * - Generator/step function/... ; with no assumption of halting, but allow to hook into any step. + * - Cache: + * - Control of (non-/)lazyness of functions + * - None as, first time called, memoize func. + * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence + * * TODO: Testing * - Test if references hold after equivalence/composition... * + * TODO: After initial demo: + * - Allow mapping/finding of other implementations regarding some equiv funcs (like different ways of implementing using NAND etc...) */ } @@ -127,6 +135,10 @@ namespace JS { export type MatchCases = [...MatchCase[], /** 'else, ... default' **/ Function.Type]; + /** + * TODO: + * - Maybe replace switch with 'zip'?, What are the practical differences? + */ export const Match = (cases: MatchCases): Function.Instance => { return Impl(self => self); // TODO } diff --git a/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md b/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md new file mode 100644 index 0000000..d0f3e7f --- /dev/null +++ b/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md @@ -0,0 +1,444 @@ + +// NOT NEEDED FOR INITIAL DEMONSTRATION: + +```ts + // TODO; Could return the ignorant reference to both instances, or just the result., .. + +/** + * - The problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. + * + * - Additionally, a copy necessarily has some non-redundancy to it: + * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy + */ +// @alias('duplicate') +copy = (): Ray => { + // return this.self.as_reference(); // Copies the reference? + throw new NotImplementedError(); + + // const copy = new Ray({ + // initial: this.self._initial().as_reference().none_or(ref => ref.copy()).as_arbitrary(), + // vertex: this.self._vertex().as_reference().none_or(ref => ref.copy()).as_arbitrary(), + // }).o({ ___dirty_copy_buffer: {} }); + // // copy._initial = () => copy.any.___dirty_copy_buffer._initial ??= this.self._initial().as_reference().copy(); + // // copy._vertex = () => copy.any.___dirty_copy_buffer._vertex ??= this.self._vertex().as_reference().copy(); + // // copy._terminal = () => copy.any.___dirty_copy_buffer._terminal ??= this.self._terminal().as_reference().copy(); + // + // + // // TODO: Doesn't copy .any + // + // return copy.as_reference(); +} + + + get count(): Ray { return JS.Number(this.as_array().length); } + + +// TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. ; each individually, again, additional structure... + +// TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? +is_vertex_equivalent = (b: Ray) => { + +} + + +// none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); + + +// TODO: IS JUST .NEXT/.previous (depending on whether its implementation is a modular structure) on boundaries +const opposite = (boundary: Boundary): Boundary => boundary === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL; + + +/** + * https://en.wikipedia.org/wiki/Homoiconicity + */ +export interface PossiblyHomoiconic> { + get self(): T; + is_reference: () => boolean + as_reference: () => T +} + + + // pop = (): Ray => { +// this.last().previous().all.terminal = (ref) => ref.___empty_terminal(); +// } +// pop = (): Ray => this.___primitive_switch({ +// [RayType.VERTEX]: () => { +// const previous_vertex = this.self.initial.follow(Ray.directions.previous); +// +// if (this.is_none()) { +// return this; // TODO; Already empty, perhaps throw +// } +// +// return previous_vertex.___primitive_switch({ +// [RayType.VERTEX]: () => { +// console.log(previous_vertex) +// // TODO: NONHACKY +// +// previous_vertex.self.terminal = new Ray({ vertex: Ray.None, initial: previous_vertex.self.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() +// return previous_vertex; +// } +// }); +// } +// }); + + + // zip also compose??? + // [a, b, c] zip [d, e, f] zip [g, h, i] ... + // [[a,d,g],[b,e,h],[c,f,i]] +static zip = JS.Function.Impl((initial, terminal) => { + + if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) + throw new PreventsImplementationBug('TODO: Implement'); + + if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) + throw new PreventsImplementationBug('TODO: Implement'); + + throw new NotImplementedError(); + // initial.traverse() + // return new Ray({ + // + // }); +}); +zip = Ray.zip.as_method(this); + +/** + * TODO: This should be constructed at the vertex and in general unsolvable + * + * TODO: Setup labels + * TODO: Use JavaScript engine for generating these for a default impl without someone supplying their own gen func?? + * TODO: + allow for searching/doing stuff based on some label ; this can be arbitrarily through the structure + */ +static _label: number = 0; +get label(): string { + if (this.any.label !== undefined) + return this.any.label; + + return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; +} + + /** + * Used for chaining JavaScript-provided properties + * + * TODO: DOESNT FOLLOW .ANY PATTERN? + */ +o = (object: { [key: string | symbol]: any }): Ray => { + _.keys(object).forEach(key => this.proxy()[key] = object[key]); // TODO: Can be prettier, TODO: map to Ray equivalents and add to vertices.. + return this; +} + +// All these are dirty +o2 = ({ initial, vertex, terminal }: any): Ray => { + if (initial) this.initial.o(initial); + if (vertex) this.o(vertex); + if (terminal) this.terminal.o(terminal); + + return this; +} + + // TODO: Cast to Any JS Class wrap/cast? + test self-referentially with Rays??? + cast = (): T => { throw new NotImplementedError(); } // TODO this.proxy(); + + + /** + * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. + */ +// JS.AsyncGenerator +async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } +// JS.Generator +*[Symbol.iterator](): Generator { yield *this.traverse(); } +// JS.AsyncGenerator +as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); +// JS.AsyncIterator +as_async_iterator = (): AsyncIterator => this.as_async_generator(); +// JS.Iterator +as_generator = (): Generator => this[Symbol.iterator](); +// JS.AsyncIterator +as_iterator = (): Iterator => this.as_generator(); +// JS.Array +as_array = (): Ray[] => [...this]; +// JS.String +toString = (): string => this.as_string(); +as_string = (): string => this.as_array().map(ref => ref.any.js).join(','); // TODO: PROPER + +as_int = (): number => { throw new NotImplementedError(); } +as_number = this.as_int; + + // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS + // apply = (func: Ray) => { + +// TODO: Combine into generalized [x, min/max()] - preserve terminal/initial structure +// TODO: ray#apply. +// TODO: FROM COMPOSER +/** + * const func = [min(), '', max()] + * + * const [min_x, max_x] = [ + * // Compute the min x-coordinate of the edges and vertices in the other graph. + * compose.terminal.x.min(), // min_other + * + * // Compute the max x-coordinate of the edges and vertices in this graph. + * compose.initial.x.max(), // max_self + * ] + */ +// } + + // TODO: +default, in the case of Initial/Terminal = Ray.None, to which the default sometimes is nothing. Or in the case of min/max it's 0. + + // [this.vertices().x.max(), this.edges().x.max()].max() + // [this.vertices().x.min(), this.edges().x.max()].max() + // TODO: Indicies not corresponding the the directionality defined, are probably on another abstraction layer described this way. More accurately, they're directly connected, and on a separate layer with more stuff in between... +get index(): Ray { throw new NotImplementedError(); } +// TODO: Can probably generate these on the fly, or cache them automatically +// TODO: being called min.x needs to return the min value within that entire structure. + +min = (_default: 0): Ray => { throw new NotImplementedError(); } +max = (_default: 0): Ray => { throw new NotImplementedError(); } + + map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } +// filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + + get clear(): Ray { throw new NotImplementedError(); } + + /** + * TODO - Better 'value' here. (Use JS.Any??) + * + * TODO: All these should accept Ray values. + * + * .size, since .length is reserved by JavaScript. + * TODO: .size could be more tensor-like, arbitrary lengths.. + */ +// @alias('length', 'of_length') +static size = (of: number, value: any = undefined): Ray => { + let ret: Ray | undefined; + let current: Ray | undefined; + // TODO: Actual good implementation: Should be lazy + for (let i = 0; i < of; i++) { + const vertex = Ray.vertex().o({js: value}).as_reference(); + + if (!ret) { + current = ret = vertex; + } else { + current = current?.compose(vertex); + } + } + + if (!ret) + return Ray.None(); + + return ret; +} +static at = (index: number, of: number, value: any = undefined): Ray => { + return Ray.size(of, value).at(index); +} +/** + * Just uses length/size for permutation. TODO: More complex permutation/enumeration implementation should follow at some point. (@see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=One%20of%20them%20could%20even%20be%20putting%20both%20our%20points%20on%20our%20selection for an example) + * + * @see "Combinatorics as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Combinatorics%20%2D%20Combinatorics%20as%20Equivalence + */ +static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( + // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) + permutation ?? 0, + // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. + permutation === undefined ? 1 : of +) + +at = (steps: number | Ray | JS.ParameterlessFunction): Ray => { + if (!JS.is_number(steps)) + throw new NotImplementedError('Not yet implemented for Rays.'); + + // TODO: Actual good implementation - also doesn't support modular like this + const array = [...this.traverse( + steps < 0 ? Ray.directions.previous : Ray.directions.next + )]; + + steps = Math.abs(steps); + + return array.length > steps && steps >= 0 ? ( + array[steps] ?? Ray.None() // TODO FIX: Probably a JavaScript quirck with some weird numbers, just failsafe to None. + ) : Ray.None(); +} + +// export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); + +``` + + +export class Ray + // implements + // AsyncIterable, + // Iterable + // Array + // Dict?? +{ + + /** + * JavaScript Array + */ + // [n: number]: Ray; + // + // readonly [Symbol.unscopables]: { [K in keyof any[]]?: boolean }; + // length: number; + // + // [Symbol.iterator](): IterableIterator { + // return undefined; + // } + // + // at(index: number): Ray | undefined { + // return undefined; + // } + // + // concat(...items: ConcatArray[]): Ray[]; + // concat(...items: (ConcatArray | Ray)[]): Ray[]; + // concat(...items: (ConcatArray | Ray)[]): Ray[] { + // return []; + // } + // + // copyWithin(target: number, start: number, end?: number): this { + // return undefined; + // } + // + // entries(): IterableIterator<[number, Ray]> { + // return undefined; + // } + // + // every(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): this is S[]; + // every(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean; + // every(predicate, thisArg?: any): any { + // } + // + // fill(value: Ray, start?: number, end?: number): this { + // return undefined; + // } + // + // filter(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S[]; + // filter(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray[]; + // filter(predicate, thisArg?: any): any { + // } + // + // find(predicate: (value: Ray, index: number, obj: Ray[]) => value is S, thisArg?: any): S | undefined; + // find(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // find(predicate, thisArg?: any): any { + // } + // + // findIndex(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): number { + // return 0; + // } + // + // findLast(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S | undefined; + // findLast(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // findLast(predicate, thisArg?: any): any { + // } + // + // findLastIndex(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): number { + // return 0; + // } + // + // flat(depth?: D): FlatArray[] { + // return []; + // } + // + // flatMap(callback: (this: This, value: Ray, index: number, array: Ray[]) => (ReadonlyArray | U), thisArg?: This): U[] { + // return []; + // } + // + // forEach(callbackfn: (value: Ray, index: number, array: Ray[]) => void, thisArg?: any): void { + // } + // + // includes(searchElement: Ray, fromIndex?: number): boolean { + // return false; + // } + // + // indexOf(searchElement: Ray, fromIndex?: number): number { + // return 0; + // } + // + // join(separator?: string): string { + // return ""; + // } + // + // keys(): IterableIterator { + // return undefined; + // } + // + // lastIndexOf(searchElement: Ray, fromIndex?: number): number { + // return 0; + // } + // + // map(callbackfn: (value: Ray, index: number, array: Ray[]) => U, thisArg?: any): U[] { + // return []; + // } + // + // pop(): Ray | undefined { + // return undefined; + // } + // + // push(...items: Ray[]): number { + // return 0; + // } + // + // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; + // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; + // reduce(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduce(callbackfn, initialValue?): any { + // } + // + // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; + // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; + // reduceRight(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduceRight(callbackfn, initialValue?): any { + // } + // + // reverse(): Ray[] { + // return []; + // } + // + // shift(): Ray | undefined { + // return undefined; + // } + // + // slice(start?: number, end?: number): Ray[] { + // return []; + // } + // + // some(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean { + // return false; + // } + // + // sort(compareFn?: (a: Ray, b: Ray) => number): this { + // return undefined; + // } + // + // splice(start: number, deleteCount?: number): Ray[]; + // splice(start: number, deleteCount: number, ...items: Ray[]): Ray[]; + // splice(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // return []; + // } + // + // toReversed(): Ray[] { + // return []; + // } + // + // toSorted(compareFn?: (a: Ray, b: Ray) => number): Ray[] { + // return []; + // } + // + // toSpliced(start: number, deleteCount: number, ...items: Ray[]): Ray[]; + // toSpliced(start: number, deleteCount?: number): Ray[]; + // toSpliced(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // return []; + // } + // + // unshift(...items: Ray[]): number { + // return 0; + // } + // + // values(): IterableIterator { + // return undefined; + // } + // + // with(index: number, value: Ray): Ray[] { + // return []; + // } + +} + diff --git a/src/@orbitmines/explorer/REFACTOR_RENDER.md b/src/@orbitmines/explorer/REFACTOR_RENDER.md new file mode 100644 index 0000000..c3d67fe --- /dev/null +++ b/src/@orbitmines/explorer/REFACTOR_RENDER.md @@ -0,0 +1,59 @@ + + +```ts + +//TODO USED FOR DEBUG NOW +move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { + const target_ray = func(this.self); + + const target = target_ray.as_reference().o({ + ...this._dirty_store, + position: + target_ray.any.position + ?? this.any.position + ?? Ray.POSITION_OF_DOOM + }); + console.log('move', `${this.self.label.split(' ')[0]} -> ${target.self.label.split(' ')[0]}`); + + if (memory) { + if (!target_ray.any.traversed) { + Interface.any.rays.compose(target); + target_ray.any.traversed = true; + } + } else { + Interface.any.rays = [target]; + } + + return target; +} + +static POSITION_OF_DOOM = [0, 100, 0] + +// TODO: Abstract away as compilation +render_options = (Interface: Ray): Required => { + return ({ + position: + this.any.position + ?? (this.is_none() ? Ray.POSITION_OF_DOOM : Ray.POSITION_OF_DOOM), + rotation: + this.any.rotation + ?? [0, 0, 0], + scale: + this.any.scale + ?? (this.is_none() ? 1.5 : 1.5), + color: + (Ray.is_orbit(Interface.any.selection.self, this.self) && Interface.any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) + : ( + this.any.color + ?? (this.is_none() ? 'red' : { + [RayType.VERTEX]: 'orange', + [RayType.TERMINAL]: '#FF5555', + [RayType.INITIAL]: '#5555FF', + [RayType.REFERENCE]: '#555555', + }[this.type] + ) + ) + }); +} + +``` \ No newline at end of file diff --git a/src/@orbitmines/explorer/Ray2.ts b/src/@orbitmines/explorer/Ray2.ts index 3e1a452..8f82704 100644 --- a/src/@orbitmines/explorer/Ray2.ts +++ b/src/@orbitmines/explorer/Ray2.ts @@ -3,16 +3,6 @@ import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; import JS from "./JS"; -const opposite = (boundary: Boundary): Boundary => boundary === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL; - -/** - * https://en.wikipedia.org/wiki/Homoiconicity - */ -export interface PossiblyHomoiconic> { - get self(): T; - is_reference: () => boolean - as_reference: () => T -} // TODO: better debug export type DebugResult = { [label: string]: DebugRay } @@ -28,50 +18,7 @@ export type DebugRay = { _dirty_store: any } -/** - * JavaScript wrapper for a mutable value. It is important to realize that this is merely some simple JavaScript abstraction, and anything is assumed to be inherently mutable. - * - * TODO: - * - Homotopy equivalence merely as some direction/reversibility constraint on some direction, ignoring additional structure (or incorporating it into the equiv) at the vertices. (Could be loosened where certain vertex-equivalences are also part of the homotopy) - * - Induced ignorance/equivalence along arbitrary rays. - * - Usual way of thinking about vertices is what the coninuations are here - phrase that somewhjere - * - * TODO: Any javascript class, allow warpper of function names around any ray, as a possible match - * TODO: All the methods defined here should be implemented in some Ray structure at some point - * - * TODO: Maybe want a way to destroy from one end, so that if other references try to look, they won't find additional structure. - More as a javascript implementation quirck if anything? - * - * TODO: Can do some workaround overloading through properties, at least for +/- - * - * TODO: Singlke keybind for now to show/hide the ray disambiguation or 'dead edges/..'/ - * - * - * - * TODO: All methods to 'step' variant - and an intuitive way to switch between modes - * - Through better Ray.___func - * - Transform all functions on Ray to that. (Perhaps use JavaScript generators by default (more intuitively?) - Just convert using JS.Generator) - * - No assumption of halting - * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence - * - * TODO: SWITCH/MATCH - * // TODO; Maybe replace switch with 'zip'?, What are the practical differences? - * // TODO: switch/match Should be abstracted into Ray? - * - * TODO: Stylistic - * - Consistency of Arbitrary vs non-arbitrary. - * - Reorder methods in a sensible way. - * - */ -export class Ray - implements - AbstractDirectionality, - PossiblyHomoiconic, - - AsyncIterable, - Iterable - // Array - // Dict -{ +export class Ray { // /** // * Moves `this.self` and `this.self.self` to a new line. // * @@ -169,7 +116,6 @@ export class Ray - // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? @@ -257,47 +203,8 @@ export class Ray }); equivalent = Ray.equivalent.as_method(this); - // zip also compose??? - // [a, b, c] zip [d, e, f] zip [g, h, i] ... - // [[a,d,g],[b,e,h],[c,f,i]] - static zip = JS.Function.Impl((initial, terminal) => { - - if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) - throw new PreventsImplementationBug('TODO: Implement'); - if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) - throw new PreventsImplementationBug('TODO: Implement'); - - throw new NotImplementedError(); - // initial.traverse() - // return new Ray({ - // - // }); - }); - zip = Ray.zip.as_method(this); - // pop = (): Ray => { - // this.last().previous().all.terminal = (ref) => ref.___empty_terminal(); - // } - // pop = (): Ray => this.___primitive_switch({ - // [RayType.VERTEX]: () => { - // const previous_vertex = this.self.initial.follow(Ray.directions.previous); - // - // if (this.is_none()) { - // return this; // TODO; Already empty, perhaps throw - // } - // - // return previous_vertex.___primitive_switch({ - // [RayType.VERTEX]: () => { - // console.log(previous_vertex) - // // TODO: NONHACKY - // - // previous_vertex.self.terminal = new Ray({ vertex: Ray.None, initial: previous_vertex.self.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() - // return previous_vertex; - // } - // }); - // } - // }); static follow_direction = { [RayType.INITIAL]: Ray.directions.next, @@ -335,48 +242,7 @@ export class Ray has_previous = (step: JS.FunctionImpl = Ray.directions.previous): boolean => this.has_next(step); // @alias('beginning', 'front') first = (step: JS.FunctionImpl = Ray.directions.previous): Ray => this.last(step); - - // TODO: I Don't like this name, but it needs to get across that any equivalency, or any equivalency check for that necessarily, is local. And I want more equivalences, I run more of this method. - // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. - is_vertex_equivalent = (b: Ray) => { - // TODO; in the case of a list, each individually, again, additional structure... - } - // TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? - - // TODO: Whether the thing is referenced on the vertex: do their vertices have some connection onm this direction? - - get count(): Ray { return JS.Number(this.as_array().length); } - // TODO; Could return the ignorant reference to both instances, or just the result., .. - - /** - * TODO: Need more control over the (non-/)lazyness of copy. - * - * - The problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. - * - * - Additionally, a copy necessarily has some non-redundancy to it: - * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy - */ - // @alias('duplicate') - copy = (): Ray => { - // return this.self.as_reference(); // Copies the reference? - throw new NotImplementedError(); - - // const copy = new Ray({ - // initial: this.self._initial().as_reference().none_or(ref => ref.copy()).as_arbitrary(), - // vertex: this.self._vertex().as_reference().none_or(ref => ref.copy()).as_arbitrary(), - // }).o({ ___dirty_copy_buffer: {} }); - // // copy._initial = () => copy.any.___dirty_copy_buffer._initial ??= this.self._initial().as_reference().copy(); - // // copy._vertex = () => copy.any.___dirty_copy_buffer._vertex ??= this.self._vertex().as_reference().copy(); - // // copy._terminal = () => copy.any.___dirty_copy_buffer._terminal ??= this.self._terminal().as_reference().copy(); - // - // - // // TODO: Doesn't copy .any - // - // return copy.as_reference(); - } - - // none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); get reverse(): Ray { const copy = this;//TODO.copy(); @@ -390,108 +256,6 @@ export class Ray return copy; } - /** - * TODO - Better 'value' here. (Use JS.Any??) - * - * TODO: All these should accept Ray values. - * - * .size, since .length is reserved by JavaScript. - * TODO: .size could be more tensor-like, arbitrary lengths.. - */ - // @alias('length', 'of_length') - static size = (of: number, value: any = undefined): Ray => { - let ret: Ray | undefined; - let current: Ray | undefined; - // TODO: Actual good implementation: Should be lazy - for (let i = 0; i < of; i++) { - const vertex = Ray.vertex().o({js: value}).as_reference(); - - if (!ret) { - current = ret = vertex; - } else { - current = current?.compose(vertex); - } - } - - if (!ret) - return Ray.None(); - - return ret; - } - static at = (index: number, of: number, value: any = undefined): Ray => { - return Ray.size(of, value).at(index); - } - /** - * Just uses length/size for permutation. TODO: More complex permutation/enumeration implementation should follow at some point. (@see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=One%20of%20them%20could%20even%20be%20putting%20both%20our%20points%20on%20our%20selection for an example) - * - * @see "Combinatorics as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Combinatorics%20%2D%20Combinatorics%20as%20Equivalence - */ - static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( - // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) - permutation ?? 0, - // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. - permutation === undefined ? 1 : of - ) - - at = (steps: number | Ray | JS.ParameterlessFunction): Ray => { - if (!JS.is_number(steps)) - throw new NotImplementedError('Not yet implemented for Rays.'); - - // TODO: Actual good implementation - also doesn't support modular like this - const array = [...this.traverse( - steps < 0 ? Ray.directions.previous : Ray.directions.next - )]; - - steps = Math.abs(steps); - - return array.length > steps && steps >= 0 ? ( - array[steps] ?? Ray.None() // TODO FIX: Probably a JavaScript quirck with some weird numbers, just failsafe to None. - ) : Ray.None(); - } - - // export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); - - // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' - map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } - // filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } - get clear(): Ray { throw new NotImplementedError(); } - - // TODO: Generalize these functions to: - // - // TODO: +default, in the case of Initial/Terminal = Ray.None, to which the default sometimes is nothing. Or in the case of min/max it's 0. - - - // TODO: being called min.x needs to return the min value within that entire structure. - - // [this.vertices().x.max(), this.edges().x.max()].max() - // [this.vertices().x.min(), this.edges().x.max()].max() - // TODO: Indicies not corresponding the the directionality defined, are probably on another abstraction layer described this way. More accurately, they're directly connected, and on a separate layer with more stuff in between... - get index(): Ray { throw new NotImplementedError(); } - // TODO: Can probably generate these on the fly, or cache them automatically - min = (_default: 0): Ray => { throw new NotImplementedError(); } - max = (_default: 0): Ray => { throw new NotImplementedError(); } - - // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS - // apply = (func: Ray) => { - - // TODO: Combine into generalized [x, min/max()] - preserve terminal/initial structure - // TODO: ray#apply. - // TODO: FROM COMPOSER - /** - * const func = [min(), '', max()] - * - * const [min_x, max_x] = [ - * // Compute the min x-coordinate of the edges and vertices in the other graph. - * compose.terminal.x.min(), // min_other - * - * // Compute the max x-coordinate of the edges and vertices in this graph. - * compose.initial.x.max(), // max_self - * ] - */ - // } - - // ___compute = () - *traverse(step: JS.FunctionImpl = Ray.directions.next): Generator { // TODO: Also to ___func?? @@ -708,30 +472,6 @@ export class Ray } - /** - * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. - */ - // JS.AsyncGenerator - async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } - // JS.Generator - *[Symbol.iterator](): Generator { yield *this.traverse(); } - // JS.AsyncGenerator - as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); - // JS.AsyncIterator - as_async_iterator = (): AsyncIterator => this.as_async_generator(); - // JS.Iterator - as_generator = (): Generator => this[Symbol.iterator](); - // JS.AsyncIterator - as_iterator = (): Iterator => this.as_generator(); - // JS.Array - as_array = (): Ray[] => [...this]; - // JS.String - toString = (): string => this.as_string(); - as_string = (): string => this.as_array().map(ref => ref.any.js).join(','); // TODO: PROPER - - as_int = (): number => { throw new NotImplementedError(); } - as_number = this.as_int; - /** * * TODO: @@ -773,28 +513,6 @@ export class Ray */ get any(): { [key: string | symbol]: Ray } & any { return this.self.proxy(); } get ___any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } - cast = (): T => { throw new NotImplementedError(); } // TODO this.proxy(); - - /** - * Used for chaining JavaScript-provided properties - * - * TODO: DOESNT FOLLOW .ANY PATTERN? - */ - o = (object: { [key: string | symbol]: any }): Ray => { - _.keys(object).forEach(key => this.proxy()[key] = object[key]); // TODO: Can be prettier, TODO: map to Ray equivalents and add to vertices.. - return this; - } - - // All these are dirty - o2 = ({ initial, vertex, terminal }: any): Ray => { - if (initial) this.initial.o(initial); - if (vertex) this.o(vertex); - if (terminal) this.terminal.o(terminal); - - return this; - } - - protected property = (property: string | symbol, _default?: any): any => this.any[property] ??= (_default ?? Ray.None()); // TODO: Can this be prettier?? protected _proxy: any; protected _dirty_store: { [key: string | symbol]: object } = {} @@ -834,6 +552,7 @@ export class Ray * - Don't assume we can track back any reference to this thing. Just destroy it, set everything to None. And let anything else deal with the consequences of the deletion. * * TODO: + * - TODO: Maybe want a way to destroy from one end, so that if other references try to look, they won't find additional structure. - More as a javascript implementation quick if anything? * - Could lazily try to find references. * - Implement on proxy for 'delete ray' */ @@ -851,60 +570,6 @@ export class Ray return this; } - //TODO USED FOR DEBUG NOW - move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { - const target_ray = func(this.self); - - const target = target_ray.as_reference().o({ - ...this._dirty_store, - position: - target_ray.any.position - ?? this.any.position - ?? Ray.POSITION_OF_DOOM - }); - console.log('move', `${this.self.label.split(' ')[0]} -> ${target.self.label.split(' ')[0]}`); - - if (memory) { - if (!target_ray.any.traversed) { - Interface.any.rays.compose(target); - target_ray.any.traversed = true; - } - } else { - Interface.any.rays = [target]; - } - - return target; - } - - static POSITION_OF_DOOM = [0, 100, 0] - - // TODO: Abstract away as compilation - render_options = (Interface: Ray): Required => { - return ({ - position: - this.any.position - ?? (this.is_none() ? Ray.POSITION_OF_DOOM : Ray.POSITION_OF_DOOM), - rotation: - this.any.rotation - ?? [0, 0, 0], - scale: - this.any.scale - ?? (this.is_none() ? 1.5 : 1.5), - color: - (Ray.is_orbit(Interface.any.selection.self, this.self) && Interface.any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) - : ( - this.any.color - ?? (this.is_none() ? 'red' : { - [RayType.VERTEX]: 'orange', - [RayType.TERMINAL]: '#FF5555', - [RayType.INITIAL]: '#5555FF', - [RayType.REFERENCE]: '#555555', - }[this.type] - ) - ) - }); - } - ___dirty_all(c: Ray[]): Ray[] { if (c.filter(a => a.label === this.label).length !== 0) { return c; @@ -950,17 +615,6 @@ export class Ray return obj; } - /** - * TODO: This should be constructed at the vertex and in general unsolvable - */ - static _label: number = 0; - get label(): string { - if (this.any.label !== undefined) - return this.any.label; - - return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; - } - } // default = (fn: () => any): any => self.match({ @@ -968,4 +622,3 @@ export class Ray // None: () => fn() // }) // - diff --git a/src/@orbitmines/explorer/Ray3.ts b/src/@orbitmines/explorer/Ray3.ts deleted file mode 100644 index 2ef81c8..0000000 --- a/src/@orbitmines/explorer/Ray3.ts +++ /dev/null @@ -1,179 +0,0 @@ - -export class Ray - // implements - // AsyncIterable, - // Iterable - // Array -{ - - /** - * JavaScript Array - */ - // [n: number]: Ray; - // - // readonly [Symbol.unscopables]: { [K in keyof any[]]?: boolean }; - // length: number; - // - // [Symbol.iterator](): IterableIterator { - // return undefined; - // } - // - // at(index: number): Ray | undefined { - // return undefined; - // } - // - // concat(...items: ConcatArray[]): Ray[]; - // concat(...items: (ConcatArray | Ray)[]): Ray[]; - // concat(...items: (ConcatArray | Ray)[]): Ray[] { - // return []; - // } - // - // copyWithin(target: number, start: number, end?: number): this { - // return undefined; - // } - // - // entries(): IterableIterator<[number, Ray]> { - // return undefined; - // } - // - // every(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): this is S[]; - // every(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean; - // every(predicate, thisArg?: any): any { - // } - // - // fill(value: Ray, start?: number, end?: number): this { - // return undefined; - // } - // - // filter(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S[]; - // filter(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray[]; - // filter(predicate, thisArg?: any): any { - // } - // - // find(predicate: (value: Ray, index: number, obj: Ray[]) => value is S, thisArg?: any): S | undefined; - // find(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): Ray | undefined; - // find(predicate, thisArg?: any): any { - // } - // - // findIndex(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): number { - // return 0; - // } - // - // findLast(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S | undefined; - // findLast(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray | undefined; - // findLast(predicate, thisArg?: any): any { - // } - // - // findLastIndex(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): number { - // return 0; - // } - // - // flat(depth?: D): FlatArray[] { - // return []; - // } - // - // flatMap(callback: (this: This, value: Ray, index: number, array: Ray[]) => (ReadonlyArray | U), thisArg?: This): U[] { - // return []; - // } - // - // forEach(callbackfn: (value: Ray, index: number, array: Ray[]) => void, thisArg?: any): void { - // } - // - // includes(searchElement: Ray, fromIndex?: number): boolean { - // return false; - // } - // - // indexOf(searchElement: Ray, fromIndex?: number): number { - // return 0; - // } - // - // join(separator?: string): string { - // return ""; - // } - // - // keys(): IterableIterator { - // return undefined; - // } - // - // lastIndexOf(searchElement: Ray, fromIndex?: number): number { - // return 0; - // } - // - // map(callbackfn: (value: Ray, index: number, array: Ray[]) => U, thisArg?: any): U[] { - // return []; - // } - // - // pop(): Ray | undefined { - // return undefined; - // } - // - // push(...items: Ray[]): number { - // return 0; - // } - // - // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; - // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; - // reduce(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; - // reduce(callbackfn, initialValue?): any { - // } - // - // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; - // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; - // reduceRight(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; - // reduceRight(callbackfn, initialValue?): any { - // } - // - // reverse(): Ray[] { - // return []; - // } - // - // shift(): Ray | undefined { - // return undefined; - // } - // - // slice(start?: number, end?: number): Ray[] { - // return []; - // } - // - // some(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean { - // return false; - // } - // - // sort(compareFn?: (a: Ray, b: Ray) => number): this { - // return undefined; - // } - // - // splice(start: number, deleteCount?: number): Ray[]; - // splice(start: number, deleteCount: number, ...items: Ray[]): Ray[]; - // splice(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { - // return []; - // } - // - // toReversed(): Ray[] { - // return []; - // } - // - // toSorted(compareFn?: (a: Ray, b: Ray) => number): Ray[] { - // return []; - // } - // - // toSpliced(start: number, deleteCount: number, ...items: Ray[]): Ray[]; - // toSpliced(start: number, deleteCount?: number): Ray[]; - // toSpliced(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { - // return []; - // } - // - // unshift(...items: Ray[]): number { - // return 0; - // } - // - // values(): IterableIterator { - // return undefined; - // } - // - // with(index: number, value: Ray): Ray[] { - // return []; - // } - -} - From 329e98052a7a0591f657623cb9d683b8f412e40c Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Tue, 23 Jan 2024 22:48:48 +0100 Subject: [PATCH 117/138] 2024/01/23 - Should probably implement this function traversal as a debug mode on the normal rays (set for each specific ray or all), and use it to initially access the function definitions at runtime. --- src/@orbitmines/explorer/JS.spec.ts | 23 ++++++- src/@orbitmines/explorer/JS.ts | 19 +++++ src/@orbitmines/explorer/Ray.spec.ts | 4 +- src/@orbitmines/explorer/Ray.ts | 80 ++++++++++++++++------ src/@orbitmines/explorer/Ray2.ts | 6 +- src/@orbitmines/external/chyp/Chyp.spec.ts | 4 +- 6 files changed, 104 insertions(+), 32 deletions(-) diff --git a/src/@orbitmines/explorer/JS.spec.ts b/src/@orbitmines/explorer/JS.spec.ts index 8a61e76..462a219 100644 --- a/src/@orbitmines/explorer/JS.spec.ts +++ b/src/@orbitmines/explorer/JS.spec.ts @@ -1,11 +1,32 @@ -import Ray from "./Ray"; +import Ray, {Rays} from "./Ray"; import JS from "./JS"; import {previous} from "slate"; import {NotImplementedError} from "./errors/errors"; describe("JS", () => { + describe(".Function", () => { + describe(".Instance", () => { + test(".traverse", () => { + const events: any[] = []; + const traverser = Rays.New({ // TODO: Probably should have this as an extra option on Ray, with a way of selecting different functions (for example: not going further if function was already found through traversal). + proxy: Rays.ProxyHandlers.FunctionTraversal({ + callback: (event) => { + events.push({...event, params: '--', traverser: '--'}); + } + }) + }); + try { + traverser.compose(); + } catch (e) { + // + } + + expect(events).toBe(false); + }); + }) + }) // test(".Function.Ref(ref)", () => { // const method = JS.Function.Ref((ref): Ray => new Ray({ // initial: ref.self.initial.as_arbitrary(), diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts index 9f12d77..3891718 100644 --- a/src/@orbitmines/explorer/JS.ts +++ b/src/@orbitmines/explorer/JS.ts @@ -59,6 +59,17 @@ namespace JS { */ export namespace Function { + export namespace Traversal { + + export type Callback = (event: { event: Event, func: JS.Function.Instance, traverser: Ray, params?: Recursive, name: string | symbol }) => void + + export enum Event { + GET_METHOD = "GET_METHOD", + CALL_METHOD = "CALL_METHOD", + } + + } + /** {T} is just an example/desired use case. But it generalizes to any function. */ export type Type = T | Function.Instance; @@ -84,6 +95,14 @@ namespace JS { // throw new NotImplementedError(); } + traverse = (traverser: Ray, { name, callback }: { name: string | symbol, callback: JS.Function.Traversal.Callback }): Method => { + callback({ event: JS.Function.Traversal.Event.GET_METHOD, name, func: this, traverser }); + return (...params) => { + callback({ event: JS.Function.Traversal.Event.CALL_METHOD, name, func: this, traverser, params }); + return this.impl(traverser); + } + } + /** * TODO * - Compose empty as first element? Disregard none to first elemn? Or not?? diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 58c011f..66620c9 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -10,9 +10,9 @@ describe("Ray", () => { // expect(a.is_orbit(b)).toBe(false); // }); test(".dereference", () => { - const a = Rays.New(); - expect(a.dereference()).toBe(true); + + // expect(a.dereference()).toBe(true); }); // test("[A, B, C].copy", () => { diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 0b6b1bb..fba4a91 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,5 +1,6 @@ import JS from "./JS"; import {NotImplementedError} from "./errors/errors"; +import Event = JS.Function.Traversal.Event; export namespace Rays { @@ -7,6 +8,7 @@ export namespace Rays { // initial?: JS.FunctionConstructor, // self?: JS.FunctionConstructor, // terminal?: JS.FunctionConstructor, + proxy?: ProxyHandler } /** @@ -37,8 +39,9 @@ export namespace Rays { protected constructor({ // initial, self, terminal + proxy }: Rays.Constructor = {}) { - this._proxy = new Proxy(this, Rays.ProxyHandler) as unknown as Ray; + this._proxy = new Proxy(this, proxy ?? Rays.ProxyHandlers.Ray) as unknown as Ray; // this._initial = JS.Function.New(initial ?? Rays.None); // this._self = JS.Function.New(self ?? this.proxy); // this._terminal = JS.Function.New(terminal ?? Rays.None); @@ -48,32 +51,65 @@ export namespace Rays { get ___instance(): Instance { return this; } } - // TODO AS += through property, anything possible - export const ProxyHandler: ProxyHandler = { - get: (self: Instance, property: string | symbol, proxy: Ray): any => { - // /** Use any field defined on {Rays.Instance} first. */ - // const field = (self as any)[property]; - if (property === '___instance') { return self.___instance; } + export namespace ProxyHandlers { - /** Otherwise, switch to functions defined on {Rays.Functions} */ - const func = Rays.Function(property); - if (func) { return func.as_method(self.proxy); } + // TODO AS += through property, anything possible + export const Ray: ProxyHandler = { + get: (self: Instance, property: string | symbol, proxy: Ray): any => { + // /** Use any field defined on {Rays.Instance} first. */ + // const field = (self as any)[property]; + if (property === '___instance') { return self.___instance; } - /** Not implemented. */ - throw new NotImplementedError(`Called property '${String(property)}' on Ray, which has not been implemented.`); - }, + /** Otherwise, switch to functions defined on {Rays.Functions} */ + const func = Rays.Function(property); + if (func) { return func.as_method(self.proxy); } - apply: (self: Instance, thisArg: any, argArray: any[]): any => { - throw new NotImplementedError(); - }, + /** Not implemented. */ + throw new NotImplementedError(`Called property '${String(property)}' on Ray, which has not been implemented.`); + }, - set: (self: Instance, property: string | symbol, newValue: any, proxy: Ray): boolean => { - throw new NotImplementedError(); - }, + apply: (self: Instance, thisArg: any, argArray: any[]): any => { + throw new NotImplementedError(); + }, - deleteProperty: (self: Instance, property: string | symbol): boolean => { - throw new NotImplementedError(); + set: (self: Instance, property: string | symbol, newValue: any, proxy: Ray): boolean => { + throw new NotImplementedError(); + }, + + deleteProperty: (self: Instance, property: string | symbol): boolean => { + throw new NotImplementedError(); + } } + + export const FunctionTraversal = ( + { callback }: { callback: JS.Function.Traversal.Callback } + ): ProxyHandler => ({ + get: (self: Instance, property: string | symbol, proxy: Ray): any => { + // /** Use any field defined on {Rays.Instance} first. */ + // const field = (self as any)[property]; + if (property === '___instance') { return self.___instance; } + + /** Otherwise, switch to functions defined on {Rays.Functions} */ + const func = Rays.Function(property); + if (func) { return func.traverse(proxy, { name: property, callback }); } + + /** Not implemented. */ + throw new NotImplementedError(`Called property '${String(property)}' on Ray, which has not been implemented.`); + }, + + apply: (self: Instance, thisArg: any, argArray: any[]): any => { + throw new NotImplementedError(); + }, + + set: (self: Instance, property: string | symbol, newValue: any, proxy: Ray): boolean => { + throw new NotImplementedError(); + }, + + deleteProperty: (self: Instance, property: string | symbol): boolean => { + throw new NotImplementedError(); + } + }); + } export const Function = ( @@ -183,7 +219,7 @@ export namespace Rays { */ export const equivalent = JS.Function.Self.Two( (a, b) => { - throw new NotImplementedError(); + // throw new NotImplementedError(); // TODO: This is close but not quite, use the shifting thing I wrote down a few days ago: (And then use something to break the self-reference) - Either on this side. compose, or outside the definitions // This one harder to do in parallel? diff --git a/src/@orbitmines/explorer/Ray2.ts b/src/@orbitmines/explorer/Ray2.ts index 8f82704..76c16af 100644 --- a/src/@orbitmines/explorer/Ray2.ts +++ b/src/@orbitmines/explorer/Ray2.ts @@ -117,11 +117,7 @@ export class Ray { // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? - - - /** - * - */ + static equivalent = JS.Function.Impl((initial, terminal) => { /** diff --git a/src/@orbitmines/external/chyp/Chyp.spec.ts b/src/@orbitmines/external/chyp/Chyp.spec.ts index 2f1cff2..c98e088 100644 --- a/src/@orbitmines/external/chyp/Chyp.spec.ts +++ b/src/@orbitmines/external/chyp/Chyp.spec.ts @@ -1,7 +1,7 @@ describe("Chyp", () => { describe(".Graph", () => { - // test(".set_inputs", () => { + test(".set_inputs", () => { // const graph = Chyp.Graph.new() // .set_inputs(Ray.vertex().o({ js: 'B' }).as_arbitrary()) // .set_inputs(Ray.vertex().o({ js: 'A' }).as_arbitrary()); @@ -10,7 +10,7 @@ describe("Chyp", () => { // expect(graph.initial.as_reference().any.js).toBe('A'); // expect(graph.inputs.as_reference().any.js).toBe(graph.initial.as_reference().any.js); // expect(graph.inputs).toBe(graph.initial); - // }); + }); // }); // describe(".Rule", () => { From 3a4f08ecd5b11bfb2ca98eb09f04b26e05222ca1 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 24 Jan 2024 19:14:56 +0100 Subject: [PATCH 118/138] 2024/01/24 - Thinking about possible debug modes, different way of implementing as ops? - Not sure --- src/@orbitmines/explorer/JS.spec.ts | 66 +++++++++--- src/@orbitmines/explorer/JS.ts | 67 ++++++------ src/@orbitmines/explorer/Ray.ts | 157 +++++++++++++++------------- src/@orbitmines/explorer/Ray2.ts | 15 --- 4 files changed, 170 insertions(+), 135 deletions(-) diff --git a/src/@orbitmines/explorer/JS.spec.ts b/src/@orbitmines/explorer/JS.spec.ts index 462a219..782005c 100644 --- a/src/@orbitmines/explorer/JS.spec.ts +++ b/src/@orbitmines/explorer/JS.spec.ts @@ -2,6 +2,8 @@ import Ray, {Rays} from "./Ray"; import JS from "./JS"; import {previous} from "slate"; import {NotImplementedError} from "./errors/errors"; +import self_reference = Rays.Functions.self_reference; +import none = Rays.Functions.none; describe("JS", () => { describe(".Function", () => { @@ -9,21 +11,59 @@ describe("JS", () => { test(".traverse", () => { const events: any[] = []; - const traverser = Rays.New({ // TODO: Probably should have this as an extra option on Ray, with a way of selecting different functions (for example: not going further if function was already found through traversal). - proxy: Rays.ProxyHandlers.FunctionTraversal({ - callback: (event) => { - events.push({...event, params: '--', traverser: '--'}); - } - }) - }); + const ray = Rays.New(); - try { - traverser.compose(); - } catch (e) { - // - } + ray.debug( + (event) => { + events.push(event); + }, + () => { + try{ + ray.compose() + } catch (e) {} + } + ); + + expect(events.map(event => ({ + event: event.event, context: { method: { property: event.context.method.property} } + }))).toBe(false); + + }); + test(".traverse", () => { + const events: any[] = []; + const ray = Rays.New(); + + ray.debug( + (event) => { + events.push(event); + }, + () => { + // // Reference + // ray.initial = none; + // // ray.self = // SOMETHING + // ray.terminal = none; + // + // // Initial + // ray.initial = none; + // ray.self = self_reference; + // ray.terminal = self_reference; + // + // // Vertex: + // ray.initial = self_reference; + // ray.self = self_reference; + // ray.terminal = self_reference; + // + // // Terminal + // ray.initial = self_reference; + // ray.self = self_reference; + // ray.terminal = none; + } + ); + + expect(events.map(event => ({ + event: event.event, context: { method: { property: event.context.method.property} } + }))).toBe(false); - expect(events).toBe(false); }); }) }) diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts index 3891718..1e74fdf 100644 --- a/src/@orbitmines/explorer/JS.ts +++ b/src/@orbitmines/explorer/JS.ts @@ -12,12 +12,10 @@ import Ray, {Rays} from "./Ray"; namespace JS { export type ParameterlessFunction = () => T; export type ParameterlessConstructor = new () => T; - export type Constructor = new (...args: any[]) => T; + // export type Constructor = new (...args: any[]) => T; export type FunctionImpl = (ref: T) => T; export type Recursive = (T | Recursive)[]; - export type Method = (...other: Recursive) => Ray; - // // export type FunctionConstructor = // Ray @@ -33,7 +31,7 @@ namespace JS { // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY export type Enum> = { - [TKey in T[number]]: JS.Function.Instance + [TKey in T[number]]: JS.Function.Constructor } /** @@ -52,6 +50,13 @@ namespace JS { } + export type Method = { + (...other: Recursive): Ray, // TODO: IMplement this on Ray itself somehow? + constructor: Function.Constructor; + self: Ray; + property: string | symbol; + } + /** * This allows automatic conversion between "JavaScript functions/.../generators" and Rays. * @@ -59,19 +64,8 @@ namespace JS { */ export namespace Function { - export namespace Traversal { - - export type Callback = (event: { event: Event, func: JS.Function.Instance, traverser: Ray, params?: Recursive, name: string | symbol }) => void - - export enum Event { - GET_METHOD = "GET_METHOD", - CALL_METHOD = "CALL_METHOD", - } - - } - /** {T} is just an example/desired use case. But it generalizes to any function. */ - export type Type = T | Function.Instance; + export type Type = T | Function.Constructor; /** From which perspective the Function is implemented. */ enum Perspective { @@ -80,27 +74,28 @@ namespace JS { // Ref, } - export class Instance { + export class Constructor { readonly perspective: Perspective; readonly impl: (...params: Ray[]) => Ray; - constructor({ perspective, impl }: Pick) { + constructor({ perspective, impl }: Pick) { this.perspective = perspective; this.impl = impl; } - as_method = (self: Ray): Method => { - return () => { throw new NotImplementedError(); } - // throw new NotImplementedError(); - } - - traverse = (traverser: Ray, { name, callback }: { name: string | symbol, callback: JS.Function.Traversal.Callback }): Method => { - callback({ event: JS.Function.Traversal.Event.GET_METHOD, name, func: this, traverser }); - return (...params) => { - callback({ event: JS.Function.Traversal.Event.CALL_METHOD, name, func: this, traverser, params }); - return this.impl(traverser); + as_method = ({ self, property }: Pick): Method => { + const method: Method = (...params) => { + self.on({ event: 'METHOD.CALL', context: { method, params } }); + return this.impl(self); } + method.constructor = this; + method.self = self; + method.property = property; + + self.on({ event: 'METHOD.GET', context: { method } }); + + return method; } /** @@ -125,8 +120,8 @@ namespace JS { export namespace None { - export const Impl = (impl: () => Ray): Function.Instance => { - return new Function.Instance({ perspective: Perspective.None, impl }); + export const Impl = (impl: () => Ray): Function.Constructor => { + return new Function.Constructor({ perspective: Perspective.None, impl }); } } @@ -135,15 +130,15 @@ namespace JS { * Implement a function from the perspective of 'this'. */ export namespace Self { - export const Impl = (impl: (self: Ray) => Ray): Function.Instance => { - return new Function.Instance({ perspective: Perspective.Self, impl }); + export const Impl = (impl: Rays.Op.Unary | ((self: Ray) => Ray)): Function.Constructor => { + return new Function.Constructor({ perspective: Perspective.Self, impl }); } - export const Two = (impl: (a: Ray, b: Ray) => Ray): Function.Instance => { - return new Function.Instance({ perspective: Perspective.Self, impl }); // TODO: Good way to deal with arity + export const Binary = (impl: Rays.Op.Binary | ((a: Ray, b: Ray) => Ray)): Function.Constructor => { + return new Function.Constructor({ perspective: Perspective.Self, impl }); // TODO: Good way to deal with arity } - export const If = (impl: (self: Ray) => Ray): Function.Instance => { + export const If = (impl: (self: Ray) => Ray): Function.Constructor => { return Impl(impl); // TODO: GENERIC collapse to boolean implemented and overridable } @@ -158,7 +153,7 @@ namespace JS { * TODO: * - Maybe replace switch with 'zip'?, What are the practical differences? */ - export const Match = (cases: MatchCases): Function.Instance => { + export const Match = (cases: MatchCases): Function.Constructor => { return Impl(self => self); // TODO } } diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index fba4a91..23d62a3 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,6 +1,5 @@ -import JS from "./JS"; +import JS, {Binary} from "./JS"; import {NotImplementedError} from "./errors/errors"; -import Event = JS.Function.Traversal.Event; export namespace Rays { @@ -8,7 +7,8 @@ export namespace Rays { // initial?: JS.FunctionConstructor, // self?: JS.FunctionConstructor, // terminal?: JS.FunctionConstructor, - proxy?: ProxyHandler + proxy?: ProxyHandler, + debug?: Debug.Listener, } /** @@ -20,6 +20,19 @@ export namespace Rays { export const New = (constructor?: Rays.Constructor): Ray => Rays.Instance.New(constructor).proxy; + export namespace Debug { + export type Event = { event: string, self: Ray, context: any }; + export type Listener = (event: Event) => void; + } + + export type Op = { get: (self: Ray) => Ray, set: (self: Ray) => Ray }; + export type Ops = { + initial(self: Ray): Ray; + self(self: Ray): Ray; + terminal(self: Ray): Ray; + is_orbit(a: Ray, b: Ray): boolean; + } + /** * An uninitialized empty Ray, which caches itself once initialized. */ @@ -31,6 +44,8 @@ export namespace Rays { protected readonly _proxy: Ray; + listeners: Debug.Listener[]; + // get initial(): Ray { return this._initial.call(this.proxy); } set initial(initial: JS.FunctionConstructor) { this._initial = JS.Function.New(initial); } protected _initial: JS.Function; // get self(): Ray { return this._self.call(this.proxy); } set self(self: JS.FunctionConstructor) { this._self = JS.Function.New(self); } protected _self: JS.Function; // get terminal(): Ray { return this._terminal.call(this.proxy); } set terminal(terminal: JS.FunctionConstructor) { this._terminal = JS.Function.New(terminal); } protected _terminal: JS.Function; @@ -39,8 +54,10 @@ export namespace Rays { protected constructor({ // initial, self, terminal - proxy + proxy, + debug, }: Rays.Constructor = {}) { + this.listeners = debug ? [debug] : []; this._proxy = new Proxy(this, proxy ?? Rays.ProxyHandlers.Ray) as unknown as Ray; // this._initial = JS.Function.New(initial ?? Rays.None); // this._self = JS.Function.New(self ?? this.proxy); @@ -49,49 +66,52 @@ export namespace Rays { /** Used to jump out of the proxy. */ get ___instance(): Instance { return this; } - } - export namespace ProxyHandlers { - - // TODO AS += through property, anything possible - export const Ray: ProxyHandler = { - get: (self: Instance, property: string | symbol, proxy: Ray): any => { - // /** Use any field defined on {Rays.Instance} first. */ - // const field = (self as any)[property]; - if (property === '___instance') { return self.___instance; } + debug = ( + on: Debug.Listener, + func: JS.ParameterlessFunction + ): T => { + this.listeners.push(on); + const ret = func(); + this.listeners.pop(); // TODO? - /** Otherwise, switch to functions defined on {Rays.Functions} */ - const func = Rays.Function(property); - if (func) { return func.as_method(self.proxy); } + return ret; + } - /** Not implemented. */ - throw new NotImplementedError(`Called property '${String(property)}' on Ray, which has not been implemented.`); - }, + /** Simple debug/traversal mechanism. */ + on = (event: Omit) => { + if (!this.listeners) return; - apply: (self: Instance, thisArg: any, argArray: any[]): any => { - throw new NotImplementedError(); - }, + this.listeners.forEach(listener => listener({ ...event, self: this.proxy })); + } - set: (self: Instance, property: string | symbol, newValue: any, proxy: Ray): boolean => { - throw new NotImplementedError(); - }, + } - deleteProperty: (self: Instance, property: string | symbol): boolean => { - throw new NotImplementedError(); - } + export namespace Op { + // Should not need anything elese ; so could be any one thing? + export enum Unary { + INITIAL, + SELF, // TODO .as_reference? Basically, Ray.directions + TERMINAL } + export enum Binary { + IS_ORBIT // a.___instance === b.___instance + } + } + + export namespace ProxyHandlers { - export const FunctionTraversal = ( - { callback }: { callback: JS.Function.Traversal.Callback } - ): ProxyHandler => ({ + // TODO AS += through property, anything possible + export const Ray = ({ get: (self: Instance, property: string | symbol, proxy: Ray): any => { - // /** Use any field defined on {Rays.Instance} first. */ - // const field = (self as any)[property]; - if (property === '___instance') { return self.___instance; } + // self.on({ event: 'PROXY.GET', context: { } }); + + /** Use any field on {Rays.Instance}, which we want to delegate to, first. */ + if (property === '___instance' || property === 'debug' || property === 'on') { return self[property]; } /** Otherwise, switch to functions defined on {Rays.Functions} */ const func = Rays.Function(property); - if (func) { return func.traverse(proxy, { name: property, callback }); } + if (func) { return func.as_method({ self: proxy, property }); } /** Not implemented. */ throw new NotImplementedError(`Called property '${String(property)}' on Ray, which has not been implemented.`); @@ -108,7 +128,7 @@ export namespace Rays { deleteProperty: (self: Instance, property: string | symbol): boolean => { throw new NotImplementedError(); } - }); + }) } @@ -166,31 +186,27 @@ export namespace Rays { * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. */ - export const is_orbit = JS.Function.Self.Two( - (a, b) => a.___instance === b.___instance - ); + export const is_orbit = JS.Function.Self.Binary(Op.Binary.IS_ORBIT); export const self_reference = JS.Function.Self.Impl( self => self ); + // @alias('destroy', 'clear', 'delete') + export const none = JS.Function.Self.Impl( + self => Rays.New({ }) // TODO self: self_reference + ); /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ - export const terminal = JS.Function.Self.Impl( - self => self.___instance.terminal // TODO .as_reference? Basically, Ray.directions - ); + export const terminal = JS.Function.Self.Impl(Op.Unary.TERMINAL); /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ - export const initial = JS.Function.Self.Impl( - self => self.___instance.initial // TODO .as_reference? - ); + export const initial = JS.Function.Self.Impl(Op.Unary.INITIAL); /** * An arbitrary Ray, defining what our current position is equivalent to. * * Moving to the intersecting Ray at `.self` - as a way of going an abstraction layer (lower), and asking what's inside. */ // @alias('dereference', 'self') - export const dereference = JS.Function.Self.Impl( - self => self.___instance.self // TODO .as_reference? - ); + export const dereference = JS.Function.Self.Impl(Op.Unary.SELF); export const self = dereference; /** @@ -204,7 +220,7 @@ export namespace Rays { * @see "Continuations as Equivalence (can often be done in parallel - not generally)": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence */ // @alias('merge, 'continues_with', 'compose') - export const compose = JS.Function.Self.Two( + export const compose = JS.Function.Self.Binary( (a, b) => a.terminal().equivalent(b.initial()) ); @@ -217,7 +233,7 @@ export namespace Rays { * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies */ - export const equivalent = JS.Function.Self.Two( + export const equivalent = JS.Function.Self.Binary( (a, b) => { // throw new NotImplementedError(); @@ -226,7 +242,7 @@ export namespace Rays { return a.self().compose(b.self()); }); - export const is_equivalent = JS.Function.Self.Two( + export const is_equivalent = JS.Function.Self.Binary( (a, b) => { // TODO: = COMPOSE throw new NotImplementedError(); @@ -251,41 +267,40 @@ export namespace Rays { return self; }); - // @alias('not', 'reverse', 'swap', 'converse') - export const not = JS.Function.Self.Impl((self) => { - throw new NotImplementedError(); - return self; - }); - export const and = JS.Function.Self.Two((a, b) => { - throw new NotImplementedError(); - return self; - }); - export const or = JS.Function.Self.Two((a, b) => { - throw new NotImplementedError(); - return self; - }); - export const xor = JS.Function.Self.Two((a, b) => { + // @alias('not', 'reverse', 'swap', 'converse', 'negative', 'neg') + // export const not = JS.Function.Self.Impl(self => ); + // self.terminal = self.initial(); + // self.initial = self.terminal(); + // self.not().not() = self + // TODO: What's the difference in context between stepping after not / or not doing so. + // TODO; OR BINARY? - "It's just always .next from some perspective?" + export const not = JS.Function.Self.Binary((a, b) => b); + + export const and = JS.Function.Self.Binary((a, b) => ); + export const or = JS.Function.Self.Binary((a, b) => { throw new NotImplementedError(); return self; }); - export const nand = JS.Function.Self.Two((a, b) => a.and(b).not()); - export const nor = JS.Function.Self.Two((a, b) => a.or(b).not()); + export const xor = JS.Function.Self.Binary((a, b) => a.xnor(b).not()); + export const xnor = JS.Function.Self.Binary((a, b) => a.is_orbit(b)); // TODO: Could be 'is_equivalent' too? + export const nand = JS.Function.Self.Binary((a, b) => a.and(b).not()); + export const nor = JS.Function.Self.Binary((a, b) => a.or(b).not()); // @alias(`push_{last.alias}`) - export const push_back = JS.Function.Self.Two( + export const push_back = JS.Function.Self.Binary( (a, b) => a.last().compose(b) ); // @alias(`push_{first.alias}`) - export const push_front = JS.Function.Self.Two( + export const push_front = JS.Function.Self.Binary( (a, b) => b.compose(a.first()) ); } } -type Ray = Pick & { - [TKey in keyof typeof Rays.Functions]: typeof Rays.Functions[TKey] extends JS.Function.Instance +type Ray = Pick & { + [TKey in keyof typeof Rays.Functions]: typeof Rays.Functions[TKey] extends JS.Function.Constructor ? JS.Method : never; } diff --git a/src/@orbitmines/explorer/Ray2.ts b/src/@orbitmines/explorer/Ray2.ts index 76c16af..32d4835 100644 --- a/src/@orbitmines/explorer/Ray2.ts +++ b/src/@orbitmines/explorer/Ray2.ts @@ -3,21 +3,6 @@ import {NotImplementedError, PreventsImplementationBug} from "./errors/errors"; import {InterfaceOptions} from "./OrbitMinesExplorer"; import JS from "./JS"; - -// TODO: better debug -export type DebugResult = { [label: string]: DebugRay } -export type DebugRay = { - label: string, - initial: string, - vertex: string, - terminal: string, - is_initial: boolean, - is_vertex: boolean, - is_terminal: boolean, - type: RayType, - _dirty_store: any -} - export class Ray { // /** // * Moves `this.self` and `this.self.self` to a new line. From 6ac4b7d0e9a3853d3c9440a44083805867645ed2 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 00:29:06 +0100 Subject: [PATCH 119/138] 2024/01/25 - Moving some stuff around for a beautiful JavaScript implementation --- README.md | 50 +++++- src/@orbitmines/explorer/JS.spec.ts | 102 +++++------ src/@orbitmines/explorer/JS.ts | 108 ++++++------ src/@orbitmines/explorer/JS2.ts | 21 --- .../REFACTOR_AFTER_WORKING_TRAVERSE.md | 38 ----- src/@orbitmines/explorer/Ray.ts | 160 ++++++++++++------ src/@orbitmines/explorer/Ray2.ts | 38 +---- tsconfig.json | 1 + 8 files changed, 273 insertions(+), 245 deletions(-) diff --git a/README.md b/README.md index c8c3f42..1ac6410 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ ## What is this?, What is OrbitMines?, What are Rays? -A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hyper-/)'Edge', (hyper-/)'Graph', (hyper-/)'Rule', (hyper-/)'Tactic', (hyper-/)..., (hyper-/)'Rewrite' are merged into one thing: a [Ray](https://github.com/orbitmines/orbitmines.com/blob/main/src/%40orbitmines/explorer/Ray.ts). It handles surrounding context, ignorances, equivalences, ..., differentiation. (And if it cannot, then it offers a way of implementing it for all of the above) +A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hyper-/)'Edge', (hyper-/)'Graph', (hyper-/)'Rule', (hyper-/)'Tactic', (hyper-/)..., (hyper-/)'Rewrite' are merged into one thing: a [Ray](https://github.com/orbitmines/orbitmines.com/blob/main/src/%40orbitmines/explorer/Ray.ts). It handles surrounding context, ignorances, equivalences, ..., differentiation (And if it cannot, then it offers a way of implementing it for all of the above). + +Most importantly, it is here as infrastructure. Infrastructure for the design and implementation of a different category of (programming) interfaces. - If you prefer **text**, see [2023-12-31. On Orbits, Equivalence and Inconsistencies](https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies), or more generally my/OrbitMines writing can be found here: [orbitmines.com/profiles/fadi-shawki](https://orbitmines.com/profiles/fadi-shawki). @@ -23,7 +25,7 @@ A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hype - If you prefer discussions on **Discord**: [discord.orbitmines.com](https://discord.orbitmines.com). -- Or if prefer smashing your keyboard till there's something interesting on the screen. See a first implementation of this *explorational interface*: [orbitmines.com/explorer/github.com/akissinger/chyp](https://orbitmines.com/explorer/github.com/akissinger/chyp). +- TODO: ~~Or if prefer smashing your keyboard till there's something interesting on the screen. See a first implementation of this *explorational interface*: [orbitmines.com/explorer/github.com/akissinger/chyp](https://orbitmines.com/explorer/github.com/akissinger/chyp).~~ --- @@ -64,4 +66,48 @@ A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hype ## JavaScript Interface Examples +> [!WARNING] +> Reasoning backwards, what should the JavaScript interface look like? + - [ ] Applying a function on a Ray (vertex/initial/terminal) ; then go inside, insde can again be a vertex/initial/terminal on each vertex, apply on those. + +--- + +Let's take logic gates as an example? + +```ts +const initial = Rays.boolean().orbit().size(2); +const terminal = Rays.boolean().orbit().size(2); + + + +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/@orbitmines/explorer/JS.spec.ts b/src/@orbitmines/explorer/JS.spec.ts index 782005c..82a6193 100644 --- a/src/@orbitmines/explorer/JS.spec.ts +++ b/src/@orbitmines/explorer/JS.spec.ts @@ -10,59 +10,65 @@ describe("JS", () => { describe(".Instance", () => { test(".traverse", () => { - const events: any[] = []; - const ray = Rays.New(); + // const events: any[] = []; + const ray: Ray = Rays.New(); - ray.debug( - (event) => { - events.push(event); - }, - () => { - try{ - ray.compose() - } catch (e) {} - } - ); + // const b = ray in ray; - expect(events.map(event => ({ - event: event.event, context: { method: { property: event.context.method.property} } - }))).toBe(false); + ray.initial = new ray() + + // ray()()()()(); + // + // ray.debug( + // (event) => { + // events.push(event); + // }, + // () => { + // try{ + // ray.compose() + // } catch (e) {} + // } + // ); + // + // expect(events.map(event => ({ + // event: event.event, context: { method: { property: event.context.method.property} } + // }))).toBe(false); }); test(".traverse", () => { - const events: any[] = []; - const ray = Rays.New(); - - ray.debug( - (event) => { - events.push(event); - }, - () => { - // // Reference - // ray.initial = none; - // // ray.self = // SOMETHING - // ray.terminal = none; - // - // // Initial - // ray.initial = none; - // ray.self = self_reference; - // ray.terminal = self_reference; - // - // // Vertex: - // ray.initial = self_reference; - // ray.self = self_reference; - // ray.terminal = self_reference; - // - // // Terminal - // ray.initial = self_reference; - // ray.self = self_reference; - // ray.terminal = none; - } - ); - - expect(events.map(event => ({ - event: event.event, context: { method: { property: event.context.method.property} } - }))).toBe(false); + // const events: any[] = []; + // const ray = Rays.New(); + // + // ray.debug( + // (event) => { + // events.push(event); + // }, + // () => { + // // // Reference + // // ray.initial = none; + // // // ray.self = // SOMETHING + // // ray.terminal = none; + // // + // // // Initial + // // ray.initial = none; + // // ray.self = self_reference; + // // ray.terminal = self_reference; + // // + // // // Vertex: + // // ray.initial = self_reference; + // // ray.self = self_reference; + // // ray.terminal = self_reference; + // // + // // // Terminal + // // ray.initial = self_reference; + // // ray.self = self_reference; + // // ray.terminal = none; + // } + // ); + // + // expect(events.map(event => ({ + // event: event.event, context: { method: { property: event.context.method.property} } + // }))).toBe(false); }); }) diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts index 1e74fdf..10aa16b 100644 --- a/src/@orbitmines/explorer/JS.ts +++ b/src/@orbitmines/explorer/JS.ts @@ -16,17 +16,55 @@ namespace JS { export type FunctionImpl = (ref: T) => T; export type Recursive = (T | Recursive)[]; - // - // export type FunctionConstructor = - // Ray - // | ParameterlessFunction - // | Function; - - // export type Interface = { - // [TKey in keyof T]: T[TKey] extends JS.Function - // ? JS.Method - // : never; - // } + /** + * Slightly more beautiful abstraction on top of JavaScript's proxy. + */ + export namespace Class { + export type Handler = { + apply?(self: T, args: any[]): any; + construct?(self: T, args: any[]): object; + // defineProperty?(self: T, property: string | symbol, attributes: PropertyDescriptor): boolean; + deleteProperty?(self: T, property: string | symbol): boolean; + get?(self: T, property: string | symbol): any; + // getOwnPropertyDescriptor?(self: T, property: string | symbol): PropertyDescriptor | undefined; + // getPrototypeOf?(self: T): object | null; + has?(self: T, property: string | symbol): boolean; + // isExtensible?(self: T): boolean; + // ownKeys?(self: T): ArrayLike; + // preventExtensions?(self: T): boolean; + set?(self: T, property: string | symbol, value: any): boolean; + // setPrototypeOf?(self: T, v: object | null): boolean; + } + + export type Constructor = { proxy: ProxyHandler } + + export const Handler = (handler: JS.Class.Handler): ProxyHandler => ({ + get: (___proxy_function: any, property: string | symbol, self: T): any => handler.get(self, property), + apply: (___proxy_function: any, thisArg: Ray, argArray: any[]): any => handler.apply(thisArg ?? ___proxy_function.___instance.proxy, argArray), /** thisArg can be undefined. TODO: What's the use-case of us actually using it? */ + set: (___proxy_function: any, property: string | symbol, newValue: any, self: T): boolean => handler.set(self, property, newValue), + deleteProperty: (___proxy_function: any, property: string | symbol): boolean => handler.deleteProperty(___proxy_function.___instance.proxy, property), + has(___proxy_function: any, property: string | symbol): boolean { return handler.has(___proxy_function.___instance.proxy, property); }, + construct(___proxy_function: any, argArray: any[], self: Function): object { return handler.construct(self as T, argArray); }, + }) + + export abstract class Instance { + + protected readonly _proxy: T; + + get proxy(): T { return this._proxy; } + + protected constructor(constructor: Constructor) { + /** + * Need a function here to tell the JavaScript runtime we can use it as a function & constructor. + * Doesn't really matter, since we're just catching everything in the proxy anyway. + */ + function ___proxy_function() { } + ___proxy_function.___instance = this; + + this._proxy = new Proxy(___proxy_function as any, constructor.proxy); + } + } + } // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY @@ -50,13 +88,6 @@ namespace JS { } - export type Method = { - (...other: Recursive): Ray, // TODO: IMplement this on Ray itself somehow? - constructor: Function.Constructor; - self: Ray; - property: string | symbol; - } - /** * This allows automatic conversion between "JavaScript functions/.../generators" and Rays. * @@ -109,6 +140,7 @@ namespace JS { * - Control of (non-/)lazyness of functions * - None as, first time called, memoize func. * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence + * - a.orbit() -> a.orbit(a) * * TODO: Testing * - Test if references hold after equivalence/composition... @@ -124,8 +156,14 @@ namespace JS { return new Function.Constructor({ perspective: Perspective.None, impl }); } + } + // /** + // * Implement a function from the perspective of 'this' for 'this.self'. + // */ + // // static Ref = (impl: (ref: Ray) => TResult): Function => JS.Function.Self(self => impl(self.as_reference())); + /** * Implement a function from the perspective of 'this'. */ @@ -159,42 +197,10 @@ namespace JS { } } - // export class Function { // TODO: Ray could extend Function - // - // // static New = (constructor: FunctionConstructor) => new Function(constructor); - // - // - // /** - // * Implement a function from the perspective of 'this' for 'this.self'. - // */ - // // static Ref = (impl: (ref: Ray) => TResult): Function => JS.Function.Self(self => impl(self.as_reference())); - // - // static Two = (impl: (a: Ray, b: Ray) => Ray): Function => { - // return Function.New(() => { - // throw new NotImplementedError(); - // }); - // } - // - // /** - // * - // */ // // static CachedAfterUse = (constructor: FunctionConstructor): FunctionConstructor => { // // return constructor; // // } - // - // // protected constructor(constructor: FunctionConstructor) { - // // - // // } - // - // call = (self: Ray) => { - // throw new NotImplementedError(); - // } - // - // as_method = (self: Ray): Method => { - // throw new NotImplementedError(); - // } - // - // } + /** * JavaScript runtime type checks diff --git a/src/@orbitmines/explorer/JS2.ts b/src/@orbitmines/explorer/JS2.ts index 7aabc9d..842e5a4 100644 --- a/src/@orbitmines/explorer/JS2.ts +++ b/src/@orbitmines/explorer/JS2.ts @@ -1,15 +1,6 @@ // // // -// private readonly step: JS.FunctionImpl; -// -// -// static Any = (...args: any[]): Function => { -// throw new NotImplementedError(); -// } -// -// -// // /** // * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] // */ @@ -197,18 +188,6 @@ // // } // -// export const Boolean = (boolean: boolean): Ray => { -// // TODO: Could be superpose structure instead of length 2; -// // |-false->-true-| (could of course also be reversed) -// const _false = Ray.vertex().o({ js: false }).as_reference(); -// const _true = Ray.vertex().o({ js: true }).as_reference(); -// _false.compose(_true); -// -// return (boolean ? _true : _false); -// } -// // export const bit = (bit?: boolean): Arbitrary> => permutation(bit ? 1 : 0, 2); -// export const Bit = Boolean; -// // export const Iterable = (iterable: Iterable): Ray => JS.Iterator(iterable[Symbol.iterator]()); // // export const Iterator = (iterator: Iterator): Ray => { diff --git a/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md b/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md index d0f3e7f..66acc96 100644 --- a/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md +++ b/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md @@ -44,10 +44,6 @@ is_vertex_equivalent = (b: Ray) => { // none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); -// TODO: IS JUST .NEXT/.previous (depending on whether its implementation is a modular structure) on boundaries -const opposite = (boundary: Boundary): Boundary => boundary === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL; - - /** * https://en.wikipedia.org/wiki/Homoiconicity */ @@ -58,30 +54,6 @@ export interface PossiblyHomoiconic> { } - // pop = (): Ray => { -// this.last().previous().all.terminal = (ref) => ref.___empty_terminal(); -// } -// pop = (): Ray => this.___primitive_switch({ -// [RayType.VERTEX]: () => { -// const previous_vertex = this.self.initial.follow(Ray.directions.previous); -// -// if (this.is_none()) { -// return this; // TODO; Already empty, perhaps throw -// } -// -// return previous_vertex.___primitive_switch({ -// [RayType.VERTEX]: () => { -// console.log(previous_vertex) -// // TODO: NONHACKY -// -// previous_vertex.self.terminal = new Ray({ vertex: Ray.None, initial: previous_vertex.self.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() -// return previous_vertex; -// } -// }); -// } -// }); - - // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... // [[a,d,g],[b,e,h],[c,f,i]] @@ -197,16 +169,6 @@ max = (_default: 0): Ray => { throw new NotImplementedError(); } map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } // filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } - get clear(): Ray { throw new NotImplementedError(); } - - /** - * TODO - Better 'value' here. (Use JS.Any??) - * - * TODO: All these should accept Ray values. - * - * .size, since .length is reserved by JavaScript. - * TODO: .size could be more tensor-like, arbitrary lengths.. - */ // @alias('length', 'of_length') static size = (of: number, value: any = undefined): Ray => { let ret: Ray | undefined; diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 23d62a3..9989fa0 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,13 +1,36 @@ -import JS, {Binary} from "./JS"; +import JS from "./JS"; import {NotImplementedError} from "./errors/errors"; +type Ray = + { + /** Ray is a function (.next) */ + (...other: JS.Recursive): Ray, + + /** Ray is a constructor - TODO: Copy? */ + new (...other: JS.Recursive): Ray, + } + /** JavaScript runtime conversions. */ + & Symbol + & Iterable + & AsyncIterable + + & Pick + + & { + -readonly [TKey in keyof typeof Rays.Functions]: typeof Rays.Functions[TKey] extends JS.Function.Constructor + ? Ray + : never; + } + +export default Ray; + export namespace Rays { export type Constructor = { // initial?: JS.FunctionConstructor, // self?: JS.FunctionConstructor, // terminal?: JS.FunctionConstructor, - proxy?: ProxyHandler, + proxy?: ProxyHandler, debug?: Debug.Listener, } @@ -26,23 +49,22 @@ export namespace Rays { } export type Op = { get: (self: Ray) => Ray, set: (self: Ray) => Ray }; - export type Ops = { - initial(self: Ray): Ray; - self(self: Ray): Ray; - terminal(self: Ray): Ray; - is_orbit(a: Ray, b: Ray): boolean; - } + // export type Ops = { + // initial(self: Ray): Ray; + // self(self: Ray): Ray; + // terminal(self: Ray): Ray; + // is_orbit(a: Ray, b: Ray): boolean; + // } /** * An uninitialized empty Ray, which caches itself once initialized. */ // export const None: JS.FunctionConstructor = JS.Function.CachedAfterUse(Rays.New); - export class Instance { + export class Instance extends JS.Class.Instance { static New = (constructor?: Rays.Constructor): Rays.Instance => new Rays.Instance(constructor); - protected readonly _proxy: Ray; listeners: Debug.Listener[]; @@ -50,15 +72,15 @@ export namespace Rays { // get self(): Ray { return this._self.call(this.proxy); } set self(self: JS.FunctionConstructor) { this._self = JS.Function.New(self); } protected _self: JS.Function; // get terminal(): Ray { return this._terminal.call(this.proxy); } set terminal(terminal: JS.FunctionConstructor) { this._terminal = JS.Function.New(terminal); } protected _terminal: JS.Function; - get proxy(): Ray { return this._proxy; } - protected constructor({ // initial, self, terminal proxy, debug, }: Rays.Constructor = {}) { + super({ proxy: proxy ?? ProxyHandlers.Ray }); + this.listeners = debug ? [debug] : []; - this._proxy = new Proxy(this, proxy ?? Rays.ProxyHandlers.Ray) as unknown as Ray; + // this._initial = JS.Function.New(initial ?? Rays.None); // this._self = JS.Function.New(self ?? this.proxy); // this._terminal = JS.Function.New(terminal ?? Rays.None); @@ -88,6 +110,10 @@ export namespace Rays { } export namespace Op { + export enum New { NONE, INITIAL, VERTEX, TERMINAL } + export enum Zeroary { + + } // Should not need anything elese ; so could be any one thing? export enum Unary { INITIAL, @@ -101,41 +127,66 @@ export namespace Rays { export namespace ProxyHandlers { - // TODO AS += through property, anything possible - export const Ray = ({ - get: (self: Instance, property: string | symbol, proxy: Ray): any => { + export const Ray: ProxyHandler = JS.Class.Handler({ + /** ray.property */ + get: (self: Ray, property: string | symbol): any => { // self.on({ event: 'PROXY.GET', context: { } }); /** Use any field on {Rays.Instance}, which we want to delegate to, first. */ - if (property === '___instance' || property === 'debug' || property === 'on') { return self[property]; } + if (property === '___instance' || property === 'debug' || property === 'on') { return self.___instance[property]; } /** Otherwise, switch to functions defined on {Rays.Functions} */ const func = Rays.Function(property); - if (func) { return func.as_method({ self: proxy, property }); } + if (func) { return func.as_method({ self, property }); } + + if (property === Symbol.toPrimitive) + return (hint: string) => { return 100; }; + // throw new NotImplementedError(``); /** Not implemented. */ throw new NotImplementedError(`Called property '${String(property)}' on Ray, which has not been implemented.`); }, - apply: (self: Instance, thisArg: any, argArray: any[]): any => { + /** ray.property = something; */ + set: (self: Ray, property: string | symbol, value: any): boolean => { throw new NotImplementedError(); }, - set: (self: Instance, property: string | symbol, newValue: any, proxy: Ray): boolean => { + /** delete ray.property; */ + deleteProperty: (self: Ray, property: string | symbol): boolean => { throw new NotImplementedError(); }, - deleteProperty: (self: Instance, property: string | symbol): boolean => { - throw new NotImplementedError(); - } - }) + /** ray() is called. */ + apply: (self: Ray, args: any[]): any => { + + throw new NotImplementedError(`${self}`); + }, + /** new ray() */ + construct: (self: Ray, args: any[]): object => { + throw new NotImplementedError(`${args.length} ${self}`); + }, + + /** property in ray; */ + has: (self: Ray, property: string | symbol): boolean => { + throw new NotImplementedError(`${String(property)}`); + }, + }); } export const Function = ( property: string | symbol ): (typeof Rays.Functions)[TProperty] | undefined => Rays.Functions[property as TProperty] ?? undefined; + // TODO CAN ALSO BE ZERO-ARY.. + // @alias('resize', 'size', 'structure', 'length', 'duplicate', 'copy') -> Should be generalized as any kind of structure, but with this thing repeated on it. ; use traversal or ... + export const size = JS.Function.Self.Binary( + (a, size) => { throw new NotImplementedError(); } + ); + // @alias('bit') + // export const boolean = size(2); + export namespace Functions { /** [ |-?] */ export const is_initial = JS.Function.Self.Impl( @@ -191,9 +242,14 @@ export namespace Rays { export const self_reference = JS.Function.Self.Impl( self => self ); - // @alias('destroy', 'clear', 'delete') - export const none = JS.Function.Self.Impl( - self => Rays.New({ }) // TODO self: self_reference + + // TODO: set = none; + // TODO: Destroy the current thing, connect .initial & .terminal ? (can do just direct connection, preserves 'could have been something here') - then something like [self.initial, self, self.terminal].pop(). + // TODO: Leave behind --] [-- or connect them basically.. + + // @alias('destroy', 'clear', 'delete', 'pop') + export const none = JS.Function.Self.Impl( // TODO FROM REF SPEC? + self => self.self = Op.New.NONE // TODO self: self_reference ); /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ @@ -211,6 +267,8 @@ export namespace Rays { /** * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. + * + * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) */ export const reference = JS.Function.Self.Impl( self => Rays.New({ self: self }) @@ -224,6 +282,11 @@ export namespace Rays { (a, b) => a.terminal().equivalent(b.initial()) ); + // @alias('modular', 'modulus', 'orbit') + export const orbit = JS.Function.Self.Binary( + (a, b) => a.first().initial().compose(b.last().terminal()) + ); + /** * Equivalence as "Composition of Rays." * @@ -242,30 +305,36 @@ export namespace Rays { return a.self().compose(b.self()); }); + /** + * If there exists an orbit between A & B, anywhere (so dually connected, what if only one is aware??). + */ + // @alias('includes', 'contains') ; (slightly different variants?) export const is_equivalent = JS.Function.Self.Binary( - (a, b) => { - // TODO: = COMPOSE - throw new NotImplementedError(); - return true; - }); + (a, b) => a.self().traverse().is_orbit(b.self().traverse()) // Basically: does there exist a single connection between the two? + ); + export const traverse = JS.Function.Self.Impl( + (a) => { throw new NotImplementedError(); } + ); + + + // TODO: .next but arbitrary step?? export const next = JS.Function.Self.Impl((self) => { throw new NotImplementedError(); return self; }); - export const has_next = JS.Function.Self.Impl((self) => { - throw new NotImplementedError(); - return true; - }); + export const has_next = JS.Function.Self.Impl((self) => self.next().is_some()); // @alias('end', 'result', 'back', 'output') export const last = JS.Function.Self.Impl((self) => { throw new NotImplementedError(); return self; }); - export const first = JS.Function.Self.Impl((self) => { - throw new NotImplementedError(); - return self; - }); + + export const previous = JS.Function.Self.Impl((self) => self.not().next()); + // @alias() + export const has_previous = JS.Function.Self.Impl((self) => self.not().has_next()); + // @alias('beginning', 'front') + export const first = JS.Function.Self.Impl((self) => self.not().last()); // @alias('not', 'reverse', 'swap', 'converse', 'negative', 'neg') // export const not = JS.Function.Self.Impl(self => ); @@ -274,9 +343,11 @@ export namespace Rays { // self.not().not() = self // TODO: What's the difference in context between stepping after not / or not doing so. // TODO; OR BINARY? - "It's just always .next from some perspective?" + // TODO: Level at which "not" is applied. export const not = JS.Function.Self.Binary((a, b) => b); - export const and = JS.Function.Self.Binary((a, b) => ); + export const and = JS.Function.Self.Binary((a, b) => { throw new NotImplementedError(); + } ); export const or = JS.Function.Self.Binary((a, b) => { throw new NotImplementedError(); return self; @@ -299,13 +370,6 @@ export namespace Rays { } } -type Ray = Pick & { - [TKey in keyof typeof Rays.Functions]: typeof Rays.Functions[TKey] extends JS.Function.Constructor - ? JS.Method - : never; -} -export default Ray; - /** * Other possibly names: "AbstractDirectionality, ..., ???" * @alias diff --git a/src/@orbitmines/explorer/Ray2.ts b/src/@orbitmines/explorer/Ray2.ts index 32d4835..4f8eea0 100644 --- a/src/@orbitmines/explorer/Ray2.ts +++ b/src/@orbitmines/explorer/Ray2.ts @@ -16,7 +16,7 @@ export class Ray { // } // if (this.dereference.is_none()) { // // TODO: Need some intuition for this check - // const vertex = this.___as_vertex(); + // const vertex = this.___as_vertex();1 // // if (vertex.type !== RayType.VERTEX) // throw new PreventsImplementationBug(); @@ -210,19 +210,11 @@ export class Ray { // return [...this.traverse(step)][1] ?? Ray.None(); // TODO BAD return Ray.None(); } - has_next = (step: JS.FunctionImpl = Ray.directions.next): boolean => this.next(step).is_some(); // @alias('end', 'result', 'back') last = (step: JS.FunctionImpl = Ray.directions.next): Ray => { const next = this.next(step); return next.is_some() ? next.last(step) : this; } - /** - * .previous (Just .next with a `Ray.directions.previous` default) - */ - previous = (step: JS.FunctionImpl = Ray.directions.previous): Ray => this.next(step); - has_previous = (step: JS.FunctionImpl = Ray.directions.previous): boolean => this.has_next(step); - // @alias('beginning', 'front') - first = (step: JS.FunctionImpl = Ray.directions.previous): Ray => this.last(step); get reverse(): Ray { @@ -568,34 +560,6 @@ export class Ray { return c; } - // TODO: DOESNT DO ON .SELF - debug = (c: DebugResult): DebugRay => { - if (c[this.label] !== undefined) - return c[this.label]!; - - const of = (ray: Ray): string => { - if (ray.as_reference().is_none()) return 'None'; - - ray.debug(c); - return ray.label; - } - - const obj: any = { label: this.label }; - c[this.label] = obj; - - obj.label = this.label; - obj.initial = of(this.initial); - obj.vertex = of(this.vertex); - obj.terminal = of(this.terminal); - obj.type = this.as_reference().type; - obj.is_initial = this.as_reference().is_initial(); - obj.is_vertex = this.as_reference().is_vertex(); - obj.is_terminal = this.as_reference().is_terminal(); - obj._dirty_store = this._dirty_store; - - return obj; - } - } // default = (fn: () => any): any => self.match({ diff --git a/tsconfig.json b/tsconfig.json index 16c74f0..cf5dcde 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, + "strictNullChecks": false, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", From a8634953c3700b475acf0b63c368e6654381ece0 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 14:51:48 +0100 Subject: [PATCH 120/138] 2024/01/23 - Move everything back into Ray. Only the JS specific stuff stays separated - as little separation as possible. --- README.md | 9 +- src/@orbitmines/explorer/JS.spec.ts | 54 +- src/@orbitmines/explorer/JS.ts | 169 +---- src/@orbitmines/explorer/JS2.ts | 50 +- .../explorer/OrbitMinesExplorer.tsx | 28 +- .../REFACTOR_AFTER_WORKING_TRAVERSE.md | 160 ++--- src/@orbitmines/explorer/REFACTOR_RENDER.md | 8 +- src/@orbitmines/explorer/Ray.spec.ts | 16 +- src/@orbitmines/explorer/Ray.ts | 596 +++++++++++------- src/@orbitmines/explorer/Ray2.ts | 94 +-- src/@orbitmines/explorer/Visualization.tsx | 2 +- .../explorer/debug/DebugCanvas.tsx | 34 +- .../debug/QuickVisualizationInterface.tsx | 32 +- src/@orbitmines/external/chyp/Chyp.ts | 38 +- src/@orbitmines/external/chyp/ChypCanvas.tsx | 70 +- .../external/chyp/Chyp_naive_pass.ts | 480 +++++++------- src/@orbitmines/external/chyp/README.md | 2 +- src/routes/papers/2023.OnOrbits.tsx | 2 +- 18 files changed, 904 insertions(+), 940 deletions(-) diff --git a/README.md b/README.md index 1ac6410..e93d69e 100644 --- a/README.md +++ b/README.md @@ -73,14 +73,17 @@ Most importantly, it is here as infrastructure. Infrastructure for the design an --- -Let's take logic gates as an example? +Let's take logic gates as an example? - and maybe logic with different equiv func? - Like switching between true/false on each check? ```ts -const initial = Rays.boolean().orbit().size(2); -const terminal = Rays.boolean().orbit().size(2); +import Ray from '@orbitmines/rays'; +const initial = Ray.boolean().orbit().size(2); +const terminal = Ray.boolean().orbit().size(2); +// TODO: Compiles to a sequence of traversal checks?, and setting ops?, and arbitrary many of them make up a program. + ``` diff --git a/src/@orbitmines/explorer/JS.spec.ts b/src/@orbitmines/explorer/JS.spec.ts index 82a6193..6b5eee0 100644 --- a/src/@orbitmines/explorer/JS.spec.ts +++ b/src/@orbitmines/explorer/JS.spec.ts @@ -1,43 +1,37 @@ -import Ray, {Rays} from "./Ray"; -import JS from "./JS"; -import {previous} from "slate"; -import {NotImplementedError} from "./errors/errors"; -import self_reference = Rays.Functions.self_reference; -import none = Rays.Functions.none; +import Ray from "./Ray"; describe("JS", () => { describe(".Function", () => { describe(".Instance", () => { test(".traverse", () => { - // const events: any[] = []; - const ray: Ray = Rays.New(); + const events: any[] = []; + const ray = Ray.New(); // const b = ray in ray; - ray.initial = new ray() - // ray()()()()(); // - // ray.debug( - // (event) => { - // events.push(event); - // }, - // () => { - // try{ - // ray.compose() - // } catch (e) {} - // } - // ); - // - // expect(events.map(event => ({ - // event: event.event, context: { method: { property: event.context.method.property} } - // }))).toBe(false); + ray.debug( + (event) => { + events.push(event); + }, + () => { + try{ + ray.initial = new ray() + + } catch (e) {} + } + ); + + expect(events.map(event => ({ + event: event.event, context: event.context + }))).toBe(false); }); test(".traverse", () => { // const events: any[] = []; - // const ray = Rays.New(); + // const ray = Ray.New(); // // ray.debug( // (event) => { @@ -74,7 +68,7 @@ describe("JS", () => { }) }) // test(".Function.Ref(ref)", () => { - // const method = JS.Function.Ref((ref): Ray => new Ray({ + // const method = Ray.Function.Ref((ref): Ray.Any => new Ray({ // initial: ref.self.initial.as_arbitrary(), // terminal: ref.self.terminal.as_arbitrary() // }).o({ js: ref.type })).as_method; @@ -93,7 +87,7 @@ describe("JS", () => { // expect(method(a)(b).type).toBe(RayType.VERTEX); // }); // test(".Function.WithMemory", () => { - // const square = JS.Function.WithMemory( + // const square = Ray.Function.WithMemory( // previous => previous.any.js * previous.any.js, // ); // @@ -111,7 +105,7 @@ describe("JS", () => { // expect(vertex.next().next().next().next().any.js).toBe(65536); // }); // test(".Function.Reversible", () => { - // const exp2 = JS.Function.Reversible( + // const exp2 = Ray.Function.Reversible( // previous => Math.log(previous.any.js) / Math.log(2), // previous => Math.pow(previous.any.js, 2), // ); @@ -138,7 +132,7 @@ describe("JS", () => { // // expect(ray.any.a).toBe('b'); // expect(ray.any.undefinedProperty).toBe(undefined); - // expect(() => ray.any.undefinedFunction()).toThrow(); + // expect(() => Ray.Any.any.undefinedFunction()).toThrow(); // expect(ray.any.position).toEqual([0, 1, 2]); // expect(ray.any.func()).toBe('c'); // }); @@ -239,7 +233,7 @@ describe("JS", () => { // // expect(ray.any.a).toBe('b'); // expect(ray.any.undefinedProperty).toBe(undefined); - // expect(() => ray.any.undefinedFunction()).toThrow(); + // expect(() => Ray.Any.any.undefinedFunction()).toThrow(); // expect(ray.any.position).toEqual([0, 1, 2]); // expect(ray.any.func()).toBe('c'); // } diff --git a/src/@orbitmines/explorer/JS.ts b/src/@orbitmines/explorer/JS.ts index 10aa16b..94cbee3 100644 --- a/src/@orbitmines/explorer/JS.ts +++ b/src/@orbitmines/explorer/JS.ts @@ -1,10 +1,7 @@ -import {NotImplementedError} from "./errors/errors"; import _ from "lodash"; -import Ray, {Rays} from "./Ray"; +import Ray from "./Ray"; /** - * A JavaScript interface for Rays. - * * NOTE: * - Not to be considered as a perfect mapping of JavaScript functionality - merely a practical one. * - Important to remember that this is just one particular mapping, there are probably 'many, ..., infinitely' others. @@ -20,31 +17,31 @@ namespace JS { * Slightly more beautiful abstraction on top of JavaScript's proxy. */ export namespace Class { - export type Handler = { - apply?(self: T, args: any[]): any; - construct?(self: T, args: any[]): object; + export type Handler = { + apply?(self: T, instance: Instance, args: any[]): any; + construct?(self: T, instance: Instance, args: any[]): object; // defineProperty?(self: T, property: string | symbol, attributes: PropertyDescriptor): boolean; - deleteProperty?(self: T, property: string | symbol): boolean; - get?(self: T, property: string | symbol): any; + deleteProperty?(self: T, instance: Instance, property: string | symbol): boolean; + get?(self: T, instance: Instance, property: string | symbol): any; // getOwnPropertyDescriptor?(self: T, property: string | symbol): PropertyDescriptor | undefined; // getPrototypeOf?(self: T): object | null; - has?(self: T, property: string | symbol): boolean; + has?(self: T, instance: Instance, property: string | symbol): boolean; // isExtensible?(self: T): boolean; // ownKeys?(self: T): ArrayLike; // preventExtensions?(self: T): boolean; - set?(self: T, property: string | symbol, value: any): boolean; + set?(self: T, instance: Instance, property: string | symbol, value: any): boolean; // setPrototypeOf?(self: T, v: object | null): boolean; } export type Constructor = { proxy: ProxyHandler } export const Handler = (handler: JS.Class.Handler): ProxyHandler => ({ - get: (___proxy_function: any, property: string | symbol, self: T): any => handler.get(self, property), - apply: (___proxy_function: any, thisArg: Ray, argArray: any[]): any => handler.apply(thisArg ?? ___proxy_function.___instance.proxy, argArray), /** thisArg can be undefined. TODO: What's the use-case of us actually using it? */ - set: (___proxy_function: any, property: string | symbol, newValue: any, self: T): boolean => handler.set(self, property, newValue), - deleteProperty: (___proxy_function: any, property: string | symbol): boolean => handler.deleteProperty(___proxy_function.___instance.proxy, property), - has(___proxy_function: any, property: string | symbol): boolean { return handler.has(___proxy_function.___instance.proxy, property); }, - construct(___proxy_function: any, argArray: any[], self: Function): object { return handler.construct(self as T, argArray); }, + get: (___proxy_function: any, property: string | symbol, self: T): any => handler.get(self, ___proxy_function.___instance, property), + apply: (___proxy_function: any, thisArg: Ray.Any, argArray: any[]): any => handler.apply(thisArg ?? ___proxy_function.___instance.proxy, ___proxy_function.___instance, argArray), /** thisArg can be undefined. TODO: What's the use-case of us actually using it? */ + set: (___proxy_function: any, property: string | symbol, newValue: any, self: T): boolean => handler.set(self, ___proxy_function.___instance, property, newValue), + deleteProperty: (___proxy_function: any, property: string | symbol): boolean => handler.deleteProperty(___proxy_function.___instance.proxy, ___proxy_function.___instance, property), + has(___proxy_function: any, property: string | symbol): boolean { return handler.has(___proxy_function.___instance.proxy, ___proxy_function.___instance, property); }, + construct(___proxy_function: any, argArray: any[], self: Function): object { return handler.construct(self as T, ___proxy_function.___instance, argArray); }, }) export abstract class Instance { @@ -66,146 +63,10 @@ namespace JS { } } - // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY - - export type Enum> = { - [TKey in T[number]]: JS.Function.Constructor - } - - /** - * An Enum(eration) is a (simple) Ray. - */ - export namespace Enum { - - export const Impl = >(...values: T): Enum => { - return Object.fromEntries(values.map(value => - [value, JS.Function.None.Impl((): Ray => { - throw new NotImplementedError(); // TODO - })] - )) as Enum; - // TODO: ONE OF 4 SELECTION RAY for the case of type. - } - - } - - /** - * This allows automatic conversion between "JavaScript functions/.../generators" and Rays. - * - * TODO: Is there some equivalent of this in computer science??? category theory?? - */ - export namespace Function { - - /** {T} is just an example/desired use case. But it generalizes to any function. */ - export type Type = T | Function.Constructor; - - /** From which perspective the Function is implemented. */ - enum Perspective { - None, - Self, - // Ref, - } - - export class Constructor { - - readonly perspective: Perspective; - readonly impl: (...params: Ray[]) => Ray; - - constructor({ perspective, impl }: Pick) { - this.perspective = perspective; - this.impl = impl; - } - - as_method = ({ self, property }: Pick): Method => { - const method: Method = (...params) => { - self.on({ event: 'METHOD.CALL', context: { method, params } }); - return this.impl(self); - } - method.constructor = this; - method.self = self; - method.property = property; - - self.on({ event: 'METHOD.GET', context: { method } }); - - return method; - } - - /** - * TODO - * - Compose empty as first element? Disregard none to first elemn? Or not?? - * - * TODO; Impl - * - Generally, return something which knows where all continuations are. - * - Generator/step function/... ; with no assumption of halting, but allow to hook into any step. - * - Cache: - * - Control of (non-/)lazyness of functions - * - None as, first time called, memoize func. - * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence - * - a.orbit() -> a.orbit(a) - * - * TODO: Testing - * - Test if references hold after equivalence/composition... - * - * TODO: After initial demo: - * - Allow mapping/finding of other implementations regarding some equiv funcs (like different ways of implementing using NAND etc...) - */ - } - - export namespace None { - - export const Impl = (impl: () => Ray): Function.Constructor => { - return new Function.Constructor({ perspective: Perspective.None, impl }); - } - - - } - - // /** - // * Implement a function from the perspective of 'this' for 'this.self'. - // */ - // // static Ref = (impl: (ref: Ray) => TResult): Function => JS.Function.Self(self => impl(self.as_reference())); - - /** - * Implement a function from the perspective of 'this'. - */ - export namespace Self { - export const Impl = (impl: Rays.Op.Unary | ((self: Ray) => Ray)): Function.Constructor => { - return new Function.Constructor({ perspective: Perspective.Self, impl }); - } - - export const Binary = (impl: Rays.Op.Binary | ((a: Ray, b: Ray) => Ray)): Function.Constructor => { - return new Function.Constructor({ perspective: Perspective.Self, impl }); // TODO: Good way to deal with arity - } - - export const If = (impl: (self: Ray) => Ray): Function.Constructor => { - return Impl(impl); // TODO: GENERIC collapse to boolean implemented and overridable - } - - export type MatchCase = [ - Function.Type, - Function.Type - ]; - - export type MatchCases = [...MatchCase[], /** 'else, ... default' **/ Function.Type]; - - /** - * TODO: - * - Maybe replace switch with 'zip'?, What are the practical differences? - */ - export const Match = (cases: MatchCases): Function.Constructor => { - return Impl(self => self); // TODO - } - } - - } - // // static CachedAfterUse = (constructor: FunctionConstructor): FunctionConstructor => { - // // return constructor; - // // } - - /** * JavaScript runtime type checks * - * TODO: Copy from lodash + * TODO: Copy from lodash - remove as a dependency. */ export const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); export const is_number = (_object: any): _object is number => _.isNumber(_object); diff --git a/src/@orbitmines/explorer/JS2.ts b/src/@orbitmines/explorer/JS2.ts index 842e5a4..f8080c2 100644 --- a/src/@orbitmines/explorer/JS2.ts +++ b/src/@orbitmines/explorer/JS2.ts @@ -4,7 +4,7 @@ // /** // * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] // */ -// static Ref = (impl: JS.FunctionImpl): Function => { +// static Ref = (impl: Ray.FunctionImpl): Function => { // return new Function(impl); // TODO: THIS SHOULD CHANGE, TO ON VERTEX. // } // static Impl = (impl: (initial: T, terminal: T) => T): Function => { @@ -18,13 +18,13 @@ // * TODO: Reversible through memory... // */ // static WithMemory = ( -// apply: (previous: Ray) => Ray | any +// apply: (previous: Ray.Any) => Ray.Any | any // ): Function => { // // return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); // // return { -// as_ray: (ref: Ray = Ray.None()) => { -// const next = (previous: Ray, first: boolean = false): Ray => { +// as_ray: (ref: Ray.Any = Ray.None()) => { +// const next = (previous: Ray.Any, first: boolean = false): Ray.Any => { // const result = apply(previous); // const is_terminal = result instanceof Ray ? // result.is_none() || (result.is_terminal() && result.self.is_none()) @@ -70,8 +70,8 @@ // } // // if (ref.is_none()) { -// const ray: Ray = new Ray({ -// vertex: Ray.None, +// const ray: Ray.Any = new Ray({ +// vertex: Ray.Any.None, // terminal: () => next(ray, true), // }).as_reference(); // @@ -93,18 +93,18 @@ // */ // static Reversible = = Ray>( // // @alias('backward') -// initial: (ref: Ray) => Ray | any, +// initial: (ref: Ray.Any) => Ray.Any | any, // // @alias('forward') -// terminal: (ref: Ray) => Ray | any, +// terminal: (ref: Ray.Any) => Ray.Any | any, // ): Function => { // // return Function.Ref((ref: T) => impl(ref.initial, ref.terminal)); // // return { -// as_ray: (ref: Ray = Ray.None()): Ray => { +// as_ray: (ref: Ray.Any = Ray.None()): Ray.Any => { // if (ref.is_none()) // throw new NotImplementedError(); // -// const next = (previous: Ray, direction: (ref: Ray) => Ray | any): Ray => { +// const next = (previous: Ray.Any, direction: (ref: Ray.Any) => Ray.Any | any): Ray.Any => { // const result = direction(previous); // // // TODO: COuld do this in place. @@ -136,7 +136,7 @@ // * // * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = [[a1, [[[a2]]], [[[[]]], []]], b, [[[]], [], [c]]].compose = ... // */ -// as_method = (ref: Ray): Method => ((...any: Recursive): TResult => { +// as_method = (ref: Ray.Any): Method => ((...any: Recursive): TResult => { // if (any === undefined || any.length === 0) // return this.step(ref); // @@ -178,7 +178,7 @@ // // } // }) // -// as_ray = (initial: Ray = Ray.None()): Ray => { +// as_ray = (initial: Ray.Any = Ray.None()): Ray.Any => { // throw new NotImplementedError(); // } // @@ -188,39 +188,29 @@ // // } // -// export const Iterable = (iterable: Iterable): Ray => JS.Iterator(iterable[Symbol.iterator]()); // -// export const Iterator = (iterator: Iterator): Ray => { +// +// export const Iterator = (iterator: Iterator): Ray.Any => { // // [ |--] // -// return JS.Function.WithMemory(previous => { +// return Ray.Function.WithMemory(previous => { // const iterator_result = iterator.next(); // -// return iterator_result.done !== true ? iterator_result.value : Ray.None(); +// return iterator_result.done !== true ? iterator_result.value : Ray.Any.None(); // }).as_ray(); // } // -// export const Generator = (generator: Generator): Ray => JS.Iterable(generator); -// -// // TODO Could have parallel threads in general. -// // export const AsyncGenerator = (generator: AsyncGenerator): Ray => { -// // // [ |--] -// // return JS.Iterable(generator); -// // } -// -// export const Number = (number: number): Ray => { -// throw new NotImplementedError(); -// } + // // // TODO -// export const Object = (object: object): Ray => Ray.vertex().o(object).as_reference(); +// export const Object = (object: object): Ray.Any => Ray.Any.vertex().o(object).as_reference(); // -// export const Any = (any: any): Ray => { +// export const Any = (any: any): Ray.Any => { // if (any === null || any === undefined) return JS.Any(any); // if (JS.is_boolean(any)) return JS.Boolean(any); // // if (JS.is_number(any)) return JS.Number(any); TODO // if (JS.is_iterable(any)) return JS.Iterable(any); // || is_array(any)) -// if (JS.is_function(any)) return JS.Function.Any(any).as_ray(); +// if (JS.is_function(any)) return Ray.Function.Any(any).as_ray(); // if (JS.is_object(any)) return JS.Object(any); // // // TODO diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx index 5dd58ee..5e36535 100644 --- a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx +++ b/src/@orbitmines/explorer/OrbitMinesExplorer.tsx @@ -215,15 +215,15 @@ type Options = { type RenderContext = Compiler; // Rendering is Compiling - Something which holds equivalences and ignores/shuts down self-referential structures. export type Compiler = { - coverage(ray: Ray): Ray, // Disallow dedups - covered_by(cover: Ray, ray: Ray): Compiler + coverage(ray: Ray.Any): Ray.Any, // Disallow dedups + covered_by(cover: Ray.Any, ray: Ray.Any): Compiler } class TempCompiler implements Compiler { - coverage(ray: Ray): Ray { + coverage(ray: Ray.Any): Ray.Any { return Ray.None(); } - covered_by(cover: Ray, ray: Ray): Compiler { + covered_by(cover: Ray.Any, ray: Ray.Any): Compiler { return this; } } @@ -234,12 +234,12 @@ export const AutoRay = ( initial: _default_initial, terminal: _default_terminal, ...options - }: { ray: Ray, compiler?: Compiler } & Omit & InterfaceOptions + }: { ray: Ray.Any, compiler?: Compiler } & Omit & InterfaceOptions ) => { compiler ??= new TempCompiler(); - const o = (ray: Ray, defaults: InterfaceOptions = {}): Required => { + const o = (ray: Ray.Any, defaults: InterfaceOptions = {}): Required => { const { position = defaults.position ?? [0, 0, 0], rotation = defaults.rotation ?? [0, 0, 0], @@ -251,9 +251,9 @@ export const AutoRay = ( // Move to a layer of abstraction above what is passed to us - this way we can start describing it. const ref = { // TODO; This general pattern is probably worth abstracting somewhere. - initial: ray.initial.as_reference(), - vertex: ray.as_reference(), - terminal: ray.terminal.as_reference() + initial: Ray.Any.initial.as_reference(), + vertex: Ray.Any.as_reference(), + terminal: Ray.Any.terminal.as_reference() } if (compiler.coverage(ray).is_some()) @@ -286,9 +286,9 @@ export const AutoRay = ( // // // const map: { [type: string]: { [type: string]: Pick & InterfaceOptions }} = { // [RayType.INITIAL]: { - // [RayType.INITIAL]: { type: RayType.INITIAL, position: [-20 * _default.scale, 0, 0] }, - // [RayType.VERTEX]: { type: RayType.VERTEX, position: [-20 * _default.scale, 0, 0], rotation: [0, 0, Math.PI / 2] }, - // [RayType.TERMINAL]: { type: RayType.TERMINAL }, + // [RayType.INITIAL]: { type: Ray.AnyType.INITIAL, position: [-20 * _default.scale, 0, 0] }, + // [RayType.VERTEX]: { type: Ray.AnyType.VERTEX, position: [-20 * _default.scale, 0, 0], rotation: [0, 0, Math.PI / 2] }, + // [RayType.TERMINAL]: { type: Ray.AnyType.TERMINAL }, // } // } // const initial_op = map[RayType.INITIAL][ref.initial.type]; @@ -393,7 +393,7 @@ export const SimpleRenderedRay = ( // In principle, this should be anything, this is just for the initial setup export const RenderedRay = ( - props: { reference: Ray } & { position?: [number, number, number], initial?: [number, number, number], terminal?: [number, number, number], scale?: number, color?: string } + props: { reference: Ray.Any } & { position?: [number, number, number], initial?: [number, number, number], terminal?: [number, number, number], scale?: number, color?: string } ) => { const { position = [0, 0, 0], @@ -458,7 +458,7 @@ export const RenderedRay = ( return // throw 'Not Implemented' - return + return } case RayType.VERTEX: { const tilt = -10; // TODO; Generally should use some equivalencing in the 3d-frames for this once setup is in place (perpsective/camera) if in threejs.. diff --git a/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md b/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md index 66acc96..7dcdcb1 100644 --- a/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md +++ b/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md @@ -11,7 +11,7 @@ * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy */ // @alias('duplicate') -copy = (): Ray => { +copy = (): Ray.Any => { // return this.self.as_reference(); // Copies the reference? throw new NotImplementedError(); @@ -30,18 +30,18 @@ copy = (): Ray => { } - get count(): Ray { return JS.Number(this.as_array().length); } + get count(): Ray.Any { return JS.Number(this.as_array().length); } // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. ; each individually, again, additional structure... // TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? -is_vertex_equivalent = (b: Ray) => { +is_vertex_equivalent = (b: Ray.Any) => { } -// none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); +// none_or = (arbitrary: Implementation): Ray.Any => this.is_none() ? Ray.None() : arbitrary(this); /** @@ -57,7 +57,7 @@ export interface PossiblyHomoiconic> { // zip also compose??? // [a, b, c] zip [d, e, f] zip [g, h, i] ... // [[a,d,g],[b,e,h],[c,f,i]] -static zip = JS.Function.Impl((initial, terminal) => { +static zip = Ray.Function.Impl((initial, terminal) => { if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) throw new PreventsImplementationBug('TODO: Implement'); @@ -93,13 +93,13 @@ get label(): string { * * TODO: DOESNT FOLLOW .ANY PATTERN? */ -o = (object: { [key: string | symbol]: any }): Ray => { +o = (object: { [key: string | symbol]: any }): Ray.Any => { _.keys(object).forEach(key => this.proxy()[key] = object[key]); // TODO: Can be prettier, TODO: map to Ray equivalents and add to vertices.. return this; } // All these are dirty -o2 = ({ initial, vertex, terminal }: any): Ray => { +o2 = ({ initial, vertex, terminal }: any): Ray.Any => { if (initial) this.initial.o(initial); if (vertex) this.o(vertex); if (terminal) this.terminal.o(terminal); @@ -115,19 +115,19 @@ o2 = ({ initial, vertex, terminal }: any): Ray => { * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. */ // JS.AsyncGenerator -async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } +async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } // JS.Generator -*[Symbol.iterator](): Generator { yield *this.traverse(); } +*[Symbol.iterator](): Generator { yield *this.traverse(); } // JS.AsyncGenerator -as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); +as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); // JS.AsyncIterator -as_async_iterator = (): AsyncIterator => this.as_async_generator(); +as_async_iterator = (): AsyncIterator => this.as_async_generator(); // JS.Iterator -as_generator = (): Generator => this[Symbol.iterator](); +as_generator = (): Generator => this[Symbol.iterator](); // JS.AsyncIterator -as_iterator = (): Iterator => this.as_generator(); +as_iterator = (): Iterator => this.as_generator(); // JS.Array -as_array = (): Ray[] => [...this]; +as_array = (): Ray.Any[] => [...this]; // JS.String toString = (): string => this.as_string(); as_string = (): string => this.as_array().map(ref => ref.any.js).join(','); // TODO: PROPER @@ -136,10 +136,10 @@ as_int = (): number => { throw new NotImplementedError(); } as_number = this.as_int; // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS - // apply = (func: Ray) => { + // apply = (func: Ray.Any) => { // TODO: Combine into generalized [x, min/max()] - preserve terminal/initial structure -// TODO: ray#apply. +// TODO: Ray.Any#apply. // TODO: FROM COMPOSER /** * const func = [min(), '', max()] @@ -159,20 +159,20 @@ as_number = this.as_int; // [this.vertices().x.max(), this.edges().x.max()].max() // [this.vertices().x.min(), this.edges().x.max()].max() // TODO: Indicies not corresponding the the directionality defined, are probably on another abstraction layer described this way. More accurately, they're directly connected, and on a separate layer with more stuff in between... -get index(): Ray { throw new NotImplementedError(); } +get index(): Ray.Any { throw new NotImplementedError(); } // TODO: Can probably generate these on the fly, or cache them automatically // TODO: being called min.x needs to return the min value within that entire structure. -min = (_default: 0): Ray => { throw new NotImplementedError(); } -max = (_default: 0): Ray => { throw new NotImplementedError(); } +min = (_default: 0): Ray.Any => { throw new NotImplementedError(); } +max = (_default: 0): Ray.Any => { throw new NotImplementedError(); } - map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } -// filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + map = (mapping: (ray: Ray.Any) => Ray.Any | any): Ray.Any => { throw new NotImplementedError(); } +// filter = (mapping: (ray: Ray.Any) => Ray.Any | any): Ray.Any => { throw new NotImplementedError(); } // @alias('length', 'of_length') -static size = (of: number, value: any = undefined): Ray => { - let ret: Ray | undefined; - let current: Ray | undefined; +static size = (of: number, value: any = undefined): Ray.Any => { + let ret: Ray.Any | undefined; + let current: Ray.Any | undefined; // TODO: Actual good implementation: Should be lazy for (let i = 0; i < of; i++) { const vertex = Ray.vertex().o({js: value}).as_reference(); @@ -189,7 +189,7 @@ static size = (of: number, value: any = undefined): Ray => { return ret; } -static at = (index: number, of: number, value: any = undefined): Ray => { +static at = (index: number, of: number, value: any = undefined): Ray.Any => { return Ray.size(of, value).at(index); } /** @@ -197,27 +197,27 @@ static at = (index: number, of: number, value: any = undefined): Ray => { * * @see "Combinatorics as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Combinatorics%20%2D%20Combinatorics%20as%20Equivalence */ -static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( +static permutation = (permutation: number | undefined, of: number): Ray.Any => Ray.Any.at( // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) permutation ?? 0, // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. permutation === undefined ? 1 : of ) -at = (steps: number | Ray | JS.ParameterlessFunction): Ray => { +at = (steps: number | Ray | JS.ParameterlessFunction): Ray.Any => { if (!JS.is_number(steps)) - throw new NotImplementedError('Not yet implemented for Rays.'); + throw new NotImplementedError('Not yet implemented for Ray.'); // TODO: Actual good implementation - also doesn't support modular like this const array = [...this.traverse( - steps < 0 ? Ray.directions.previous : Ray.directions.next + steps < 0 ? Ray.directions.previous : Ray.Any.directions.next )]; steps = Math.abs(steps); return array.length > steps && steps >= 0 ? ( array[steps] ?? Ray.None() // TODO FIX: Probably a JavaScript quirck with some weird numbers, just failsafe to None. - ) : Ray.None(); + ) : Ray.Any.None(); } // export const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); @@ -227,31 +227,31 @@ at = (steps: number | Ray | JS.ParameterlessFunction): Ray => { export class Ray // implements - // AsyncIterable, - // Iterable - // Array + // AsyncIterable, + // Iterable + // Array // Dict?? { /** * JavaScript Array */ - // [n: number]: Ray; + // [n: number]: Ray.Any; // // readonly [Symbol.unscopables]: { [K in keyof any[]]?: boolean }; // length: number; // - // [Symbol.iterator](): IterableIterator { + // [Symbol.iterator](): IterableIterator { // return undefined; // } // - // at(index: number): Ray | undefined { + // at(index: number): Ray.Any | undefined { // return undefined; // } // - // concat(...items: ConcatArray[]): Ray[]; - // concat(...items: (ConcatArray | Ray)[]): Ray[]; - // concat(...items: (ConcatArray | Ray)[]): Ray[] { + // concat(...items: ConcatArray[]): Ray.Any[]; + // concat(...items: (ConcatArray | Ray)[]): Ray.Any[]; + // concat(...items: (ConcatArray | Ray)[]): Ray.Any[] { // return []; // } // @@ -263,35 +263,35 @@ export class Ray // return undefined; // } // - // every(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): this is S[]; - // every(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean; + // every(predicate: (value: Ray.Any, index: number, array: Ray.Any[]) => value is S, thisArg?: any): this is S[]; + // every(predicate: (value: Ray.Any, index: number, array: Ray.Any[]) => unknown, thisArg?: any): boolean; // every(predicate, thisArg?: any): any { // } // - // fill(value: Ray, start?: number, end?: number): this { + // fill(value: Ray.Any, start?: number, end?: number): this { // return undefined; // } // - // filter(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S[]; - // filter(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray[]; + // filter(predicate: (value: Ray.Any, index: number, array: Ray.Any[]) => value is S, thisArg?: any): S[]; + // filter(predicate: (value: Ray.Any, index: number, array: Ray.Any[]) => unknown, thisArg?: any): Ray.Any[]; // filter(predicate, thisArg?: any): any { // } // - // find(predicate: (value: Ray, index: number, obj: Ray[]) => value is S, thisArg?: any): S | undefined; - // find(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // find(predicate: (value: Ray.Any, index: number, obj: Ray.Any[]) => value is S, thisArg?: any): S | undefined; + // find(predicate: (value: Ray.Any, index: number, obj: Ray.Any[]) => unknown, thisArg?: any): Ray.Any | undefined; // find(predicate, thisArg?: any): any { // } // - // findIndex(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): number { + // findIndex(predicate: (value: Ray.Any, index: number, obj: Ray.Any[]) => unknown, thisArg?: any): number { // return 0; // } // - // findLast(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S | undefined; - // findLast(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // findLast(predicate: (value: Ray.Any, index: number, array: Ray.Any[]) => value is S, thisArg?: any): S | undefined; + // findLast(predicate: (value: Ray.Any, index: number, array: Ray.Any[]) => unknown, thisArg?: any): Ray.Any | undefined; // findLast(predicate, thisArg?: any): any { // } // - // findLastIndex(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): number { + // findLastIndex(predicate: (value: Ray.Any, index: number, array: Ray.Any[]) => unknown, thisArg?: any): number { // return 0; // } // @@ -299,18 +299,18 @@ export class Ray // return []; // } // - // flatMap(callback: (this: This, value: Ray, index: number, array: Ray[]) => (ReadonlyArray | U), thisArg?: This): U[] { + // flatMap(callback: (this: This, value: Ray.Any, index: number, array: Ray.Any[]) => (ReadonlyArray | U), thisArg?: This): U[] { // return []; // } // - // forEach(callbackfn: (value: Ray, index: number, array: Ray[]) => void, thisArg?: any): void { + // forEach(callbackfn: (value: Ray.Any, index: number, array: Ray.Any[]) => void, thisArg?: any): void { // } // - // includes(searchElement: Ray, fromIndex?: number): boolean { + // includes(searchElement: Ray.Any, fromIndex?: number): boolean { // return false; // } // - // indexOf(searchElement: Ray, fromIndex?: number): number { + // indexOf(searchElement: Ray.Any, fromIndex?: number): number { // return 0; // } // @@ -322,83 +322,83 @@ export class Ray // return undefined; // } // - // lastIndexOf(searchElement: Ray, fromIndex?: number): number { + // lastIndexOf(searchElement: Ray.Any, fromIndex?: number): number { // return 0; // } // - // map(callbackfn: (value: Ray, index: number, array: Ray[]) => U, thisArg?: any): U[] { + // map(callbackfn: (value: Ray.Any, index: number, array: Ray.Any[]) => U, thisArg?: any): U[] { // return []; // } // - // pop(): Ray | undefined { + // pop(): Ray.Any | undefined { // return undefined; // } // - // push(...items: Ray[]): number { + // push(...items: Ray.Any[]): number { // return 0; // } // - // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; - // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; - // reduce(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduce(callbackfn: (previousValue: Ray.Any, currentValue: Ray.Any, currentIndex: number, array: Ray.Any[]) => Ray.Any): Ray.Any; + // reduce(callbackfn: (previousValue: Ray.Any, currentValue: Ray.Any, currentIndex: number, array: Ray.Any[]) => Ray.Any, initialValue: Ray.Any): Ray.Any; + // reduce(callbackfn: (previousValue: U, currentValue: Ray.Any, currentIndex: number, array: Ray.Any[]) => U, initialValue: U): U; // reduce(callbackfn, initialValue?): any { // } // - // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; - // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; - // reduceRight(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduceRight(callbackfn: (previousValue: Ray.Any, currentValue: Ray.Any, currentIndex: number, array: Ray.Any[]) => Ray.Any): Ray.Any; + // reduceRight(callbackfn: (previousValue: Ray.Any, currentValue: Ray.Any, currentIndex: number, array: Ray.Any[]) => Ray.Any, initialValue: Ray.Any): Ray.Any; + // reduceRight(callbackfn: (previousValue: U, currentValue: Ray.Any, currentIndex: number, array: Ray.Any[]) => U, initialValue: U): U; // reduceRight(callbackfn, initialValue?): any { // } // - // reverse(): Ray[] { + // reverse(): Ray.Any[] { // return []; // } // - // shift(): Ray | undefined { + // shift(): Ray.Any | undefined { // return undefined; // } // - // slice(start?: number, end?: number): Ray[] { + // slice(start?: number, end?: number): Ray.Any[] { // return []; // } // - // some(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean { + // some(predicate: (value: Ray.Any, index: number, array: Ray.Any[]) => unknown, thisArg?: any): boolean { // return false; // } // - // sort(compareFn?: (a: Ray, b: Ray) => number): this { + // sort(compareFn?: (a: Ray.Any, b: Ray.Any) => number): this { // return undefined; // } // - // splice(start: number, deleteCount?: number): Ray[]; - // splice(start: number, deleteCount: number, ...items: Ray[]): Ray[]; - // splice(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // splice(start: number, deleteCount?: number): Ray.Any[]; + // splice(start: number, deleteCount: number, ...items: Ray.Any[]): Ray.Any[]; + // splice(start: number, deleteCount?: number, ...items: Ray.Any[]): Ray.Any[] { // return []; // } // - // toReversed(): Ray[] { + // toReversed(): Ray.Any[] { // return []; // } // - // toSorted(compareFn?: (a: Ray, b: Ray) => number): Ray[] { + // toSorted(compareFn?: (a: Ray.Any, b: Ray.Any) => number): Ray.Any[] { // return []; // } // - // toSpliced(start: number, deleteCount: number, ...items: Ray[]): Ray[]; - // toSpliced(start: number, deleteCount?: number): Ray[]; - // toSpliced(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // toSpliced(start: number, deleteCount: number, ...items: Ray.Any[]): Ray.Any[]; + // toSpliced(start: number, deleteCount?: number): Ray.Any[]; + // toSpliced(start: number, deleteCount?: number, ...items: Ray.Any[]): Ray.Any[] { // return []; // } // - // unshift(...items: Ray[]): number { + // unshift(...items: Ray.Any[]): number { // return 0; // } // - // values(): IterableIterator { + // values(): IterableIterator { // return undefined; // } // - // with(index: number, value: Ray): Ray[] { + // with(index: number, value: Ray.Any): Ray.Any[] { // return []; // } diff --git a/src/@orbitmines/explorer/REFACTOR_RENDER.md b/src/@orbitmines/explorer/REFACTOR_RENDER.md index c3d67fe..3128710 100644 --- a/src/@orbitmines/explorer/REFACTOR_RENDER.md +++ b/src/@orbitmines/explorer/REFACTOR_RENDER.md @@ -3,7 +3,7 @@ ```ts //TODO USED FOR DEBUG NOW -move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { +move = (func: (self: Ray.Any) => Ray.Any, memory: boolean, Interface: Ray.Any): Ray.Any => { const target_ray = func(this.self); const target = target_ray.as_reference().o({ @@ -17,7 +17,7 @@ move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { if (memory) { if (!target_ray.any.traversed) { - Interface.any.rays.compose(target); + Interface.any.Ray.compose(target); target_ray.any.traversed = true; } } else { @@ -30,11 +30,11 @@ move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { static POSITION_OF_DOOM = [0, 100, 0] // TODO: Abstract away as compilation -render_options = (Interface: Ray): Required => { +render_options = (Interface: Ray.Any): Required => { return ({ position: this.any.position - ?? (this.is_none() ? Ray.POSITION_OF_DOOM : Ray.POSITION_OF_DOOM), + ?? (this.is_none() ? Ray.POSITION_OF_DOOM : Ray.Any.POSITION_OF_DOOM), rotation: this.any.rotation ?? [0, 0, 0], diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/src/@orbitmines/explorer/Ray.spec.ts index 66620c9..4af0c5e 100644 --- a/src/@orbitmines/explorer/Ray.spec.ts +++ b/src/@orbitmines/explorer/Ray.spec.ts @@ -2,8 +2,8 @@ import Ray, {Rays} from "./Ray"; describe("Ray", () => { // test(".is_orbit", () => { - // const a = Rays.New(); - // const b = Rays.New(); + // const a = Ray.New(); + // const b = Ray.New(); // // expect(a.is_orbit(a)).toBe(true); // expect(b.is_orbit(b)).toBe(true); @@ -131,7 +131,7 @@ describe("Ray", () => { // // const branch = Ray.step_function(Ray.directions.next); // -// let step: Ray = branch.as_ray(A); +// let step: Ray.Any = branch.as_ray(A); // // expect([step.previous(), step].map(ray => // [ray.dereference.is_some(), ray.dereference.type, ray.dereference.any.js]) @@ -231,7 +231,7 @@ describe("Ray", () => { // // // // let pointer = new Ray({ // // initial: () => A, -// // terminal: () => Ray.directions.next(A), +// // terminal: () => Ray.Any.directions.next(A), // // }); // // // // /** @@ -329,7 +329,7 @@ describe("Ray", () => { // // // // let pointer = new Ray({ // // initial: () => C, -// // terminal: () => Ray.directions.previous(C), +// // terminal: () => Ray.Any.directions.previous(C), // // }); // // // // expect(pointer.initial.any.js).toBe('C'); @@ -1108,7 +1108,7 @@ describe("Ray", () => { // // expect([...A_terminal.dereference.___map(ref => ref.any.js)]).toEqual(['B']); // // // // expect([...B_initial.dereference.all(Ray.directions.previous).js]).toEqual(['A']); -// // expect([...B_initial.dereference.___map(ref => ref.any.js, { step: Ray.directions.previous})]).toEqual(['A']); +// // expect([...B_initial.dereference.___map(ref => ref.any.js, { step: Ray.Any.directions.previous})]).toEqual(['A']); // // // // /** // // * | @@ -1416,7 +1416,7 @@ describe("Ray", () => { // // const iterator = A.as_iterator(); // -// let array: Ray[] = []; +// let array: Ray.Any[] = []; // // while (true) { // let current = iterator.next(); @@ -1525,7 +1525,7 @@ describe("Ray", () => { // // expect(ray.any.a).toBe('b'); // expect(ray.any.test).toBe(undefined); -// expect(() => ray.any.undefinedFunction()).toThrow(); +// expect(() => Ray.Any.any.undefinedFunction()).toThrow(); // expect(ray.any.position).toEqual([0, 1, 2]); // expect(ray.any.func()).toBe('c'); // }) diff --git a/src/@orbitmines/explorer/Ray.ts b/src/@orbitmines/explorer/Ray.ts index 9989fa0..2dd4954 100644 --- a/src/@orbitmines/explorer/Ray.ts +++ b/src/@orbitmines/explorer/Ray.ts @@ -1,89 +1,81 @@ import JS from "./JS"; import {NotImplementedError} from "./errors/errors"; -type Ray = - { - /** Ray is a function (.next) */ - (...other: JS.Recursive): Ray, - /** Ray is a constructor - TODO: Copy? */ - new (...other: JS.Recursive): Ray, - } - /** JavaScript runtime conversions. */ - & Symbol - & Iterable - & AsyncIterable +namespace Ray { - & Pick + export type Any = + { + /** Ray is a function (.next) */ + (...other: JS.Recursive): Ray.Any, - & { - -readonly [TKey in keyof typeof Rays.Functions]: typeof Rays.Functions[TKey] extends JS.Function.Constructor - ? Ray - : never; - } + /** Ray is a constructor - TODO: Copy? */ + new (...other: JS.Recursive): Ray.Any, + } + /** JavaScript runtime conversions. */ + & Symbol + & Iterable + & AsyncIterable -export default Ray; + & Pick -export namespace Rays { + & { + -readonly [TKey in keyof typeof Ray.Function.All]: typeof Ray.Function.All[TKey] extends Ray.Any + ? Ray.Any + : never; + } export type Constructor = { - // initial?: JS.FunctionConstructor, - // self?: JS.FunctionConstructor, - // terminal?: JS.FunctionConstructor, - proxy?: ProxyHandler, + // initial?: Ray.FunctionConstructor, + // self?: Ray.FunctionConstructor, + // terminal?: Ray.FunctionConstructor, + proxy?: ProxyHandler, debug?: Debug.Listener, } - /** - * TODO: Shouldn't classify these? - */ - export const Type = JS.Enum.Impl('REFERENCE', 'INITIAL', 'TERMINAL', 'VERTEX'); - - // export const Boundary = { INITIAL: Type.INITIAL, TERMINAL: Type.TERMINAL }; TODO: LIST O - - export const New = (constructor?: Rays.Constructor): Ray => Rays.Instance.New(constructor).proxy; + export const New = (constructor?: Ray.Constructor): Ray.Any => Ray.Instance.New(constructor).proxy; export namespace Debug { - export type Event = { event: string, self: Ray, context: any }; + export type Event = { event: string, self: Ray.Any, context: any }; export type Listener = (event: Event) => void; } - export type Op = { get: (self: Ray) => Ray, set: (self: Ray) => Ray }; + export type Op = { get: (self: Ray.Any) => Ray.Any, set: (self: Ray.Any) => Ray.Any }; // export type Ops = { - // initial(self: Ray): Ray; - // self(self: Ray): Ray; - // terminal(self: Ray): Ray; - // is_orbit(a: Ray, b: Ray): boolean; + // initial(self: Ray.Any): Ray.Any; + // self(self: Ray.Any): Ray.Any; + // terminal(self: Ray.Any): Ray.Any; + // is_orbit(a: Ray.Any, b: Ray.Any): boolean; // } /** * An uninitialized empty Ray, which caches itself once initialized. */ - // export const None: JS.FunctionConstructor = JS.Function.CachedAfterUse(Rays.New); + // export const None: Ray.FunctionConstructor = Ray.Function.CachedAfterUse(Ray.New); - export class Instance extends JS.Class.Instance { + export class Instance extends JS.Class.Instance { - static New = (constructor?: Rays.Constructor): Rays.Instance => new Rays.Instance(constructor); + static New = (constructor?: Ray.Constructor): Ray.Instance => new Ray.Instance(constructor); listeners: Debug.Listener[]; - // get initial(): Ray { return this._initial.call(this.proxy); } set initial(initial: JS.FunctionConstructor) { this._initial = JS.Function.New(initial); } protected _initial: JS.Function; - // get self(): Ray { return this._self.call(this.proxy); } set self(self: JS.FunctionConstructor) { this._self = JS.Function.New(self); } protected _self: JS.Function; - // get terminal(): Ray { return this._terminal.call(this.proxy); } set terminal(terminal: JS.FunctionConstructor) { this._terminal = JS.Function.New(terminal); } protected _terminal: JS.Function; + // get initial(): Ray.Any { return this._initial.call(this.proxy); } set initial(initial: Ray.FunctionConstructor) { this._initial = Ray.Function.New(initial); } protected _initial: Ray.Function; + // get self(): Ray.Any { return this._self.call(this.proxy); } set self(self: Ray.FunctionConstructor) { this._self = Ray.Function.New(self); } protected _self: Ray.Function; + // get terminal(): Ray.Any { return this._terminal.call(this.proxy); } set terminal(terminal: Ray.FunctionConstructor) { this._terminal = Ray.Function.New(terminal); } protected _terminal: Ray.Function; protected constructor({ // initial, self, terminal proxy, debug, - }: Rays.Constructor = {}) { - super({ proxy: proxy ?? ProxyHandlers.Ray }); + }: Ray.Constructor = {}) { + super({ proxy: proxy ?? Ray.ProxyHandlers.Default }); this.listeners = debug ? [debug] : []; - // this._initial = JS.Function.New(initial ?? Rays.None); - // this._self = JS.Function.New(self ?? this.proxy); - // this._terminal = JS.Function.New(terminal ?? Rays.None); + // this._initial = Ray.Function.New(initial ?? Ray.None); + // this._self = Ray.Function.New(self ?? this.proxy); + // this._terminal = Ray.Function.New(terminal ?? Ray.None); } /** Used to jump out of the proxy. */ @@ -109,6 +101,32 @@ export namespace Rays { } + export class Compiler { // Ray is Compiler + + /** + * // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY + * + * TODO + * - Compose empty as first element? Disregard none to first elemn? Or not?? + * + * TODO; Impl + * - Generally, return something which knows where all continuations are. + * - Generator/step function/... ; with no assumption of halting, but allow to hook into any step. + * - Cache: + * - Control of (non-/)lazyness of functions + * - None as, first time called, memoize func. + * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence + * - a.orbit() -> a.orbit(a) + * + * TODO: Testing + * - Test if references hold after equivalence/composition... + * + * TODO: After initial demo: + * - Allow mapping/finding of other implementations regarding some equiv funcs (like different ways of implementing using NAND etc...) + */ + + } + export namespace Op { export enum New { NONE, INITIAL, VERTEX, TERMINAL } export enum Zeroary { @@ -127,16 +145,16 @@ export namespace Rays { export namespace ProxyHandlers { - export const Ray: ProxyHandler = JS.Class.Handler({ + export const Default: ProxyHandler = JS.Class.Handler({ /** ray.property */ - get: (self: Ray, property: string | symbol): any => { - // self.on({ event: 'PROXY.GET', context: { } }); + get: (self: Ray.Any, instance: Ray.Instance, property: string | symbol): any => { + instance.on({ event: 'PROXY.GET', context: { property } }); - /** Use any field on {Rays.Instance}, which we want to delegate to, first. */ - if (property === '___instance' || property === 'debug' || property === 'on') { return self.___instance[property]; } + /** Use any field on {Ray.Instance}, which we want to delegate to, first. */ + if (property === '___instance' || property === 'debug' || property === 'on') { return instance[property]; } - /** Otherwise, switch to functions defined on {Rays.Functions} */ - const func = Rays.Function(property); + /** Otherwise, switch to functions defined on {Ray.Functions} */ + const func = Ray.Function.Get(property as any); if (func) { return func.as_method({ self, property }); } if (property === Symbol.toPrimitive) @@ -148,231 +166,329 @@ export namespace Rays { }, /** ray.property = something; */ - set: (self: Ray, property: string | symbol, value: any): boolean => { + set: (self: Ray.Any, instance: Ray.Instance, property: string | symbol, value: any): boolean => { + instance.on({ event: 'PROXY.SET', context: { property, value } }); + throw new NotImplementedError(); }, /** delete ray.property; */ - deleteProperty: (self: Ray, property: string | symbol): boolean => { + deleteProperty: (self: Ray.Any, instance: Ray.Instance, property: string | symbol): boolean => { + instance.on({ event: 'PROXY.DELETE', context: { property } }); + throw new NotImplementedError(); }, /** ray() is called. */ - apply: (self: Ray, args: any[]): any => { + apply: (self: Ray.Any, instance: Ray.Instance, args: any[]): any => { + instance.on({ event: 'PROXY.APPLY', context: { args } }); throw new NotImplementedError(`${self}`); }, /** new ray() */ - construct: (self: Ray, args: any[]): object => { + construct: (self: Ray.Any, instance: Ray.Instance, args: any[]): object => { + instance.on({ event: 'PROXY.NEW', context: { args } }); + throw new NotImplementedError(`${args.length} ${self}`); }, /** property in ray; */ - has: (self: Ray, property: string | symbol): boolean => { + has: (self: Ray.Any, instance: Ray.Instance, property: string | symbol): boolean => { + instance.on({ event: 'PROXY.HAS', context: { property } }); + throw new NotImplementedError(`${String(property)}`); }, }); } - export const Function = ( - property: string | symbol - ): (typeof Rays.Functions)[TProperty] | undefined => Rays.Functions[property as TProperty] ?? undefined; - - // TODO CAN ALSO BE ZERO-ARY.. - // @alias('resize', 'size', 'structure', 'length', 'duplicate', 'copy') -> Should be generalized as any kind of structure, but with this thing repeated on it. ; use traversal or ... - export const size = JS.Function.Self.Binary( - (a, size) => { throw new NotImplementedError(); } - ); - // @alias('bit') - // export const boolean = size(2); - - export namespace Functions { - - /** [ |-?] */ export const is_initial = JS.Function.Self.Impl( - self => self.initial().is_none() - ); - /** [--|--] */ export const is_vertex = JS.Function.Self.Impl( - self => self.is_initial().nor(self.is_terminal()) - ); - /** [?-| ] */ export const is_terminal = JS.Function.Self.Impl( - self => self.terminal().is_none() - ); - /** [ | ] */ export const is_reference = JS.Function.Self.Impl( - self => self.is_initial().and(self.is_terminal()) - ); - /** [?-| ] or [ |-?] */ export const is_boundary = JS.Function.Self.Impl( - self => self.is_initial().xor(self.is_terminal()) - ); - - export const type = JS.Function.Self.Match([ - /** [ | ] */ [is_reference, Rays.Type.REFERENCE], - /** [ |-?] */ [is_initial, Rays.Type.INITIAL], - /** [?-| ] */ [is_terminal, Rays.Type.TERMINAL], - /** [--|--] */ Rays.Type.VERTEX - ]); + export type Enum> = { + [TKey in T[number]]: Ray.Any + } + /** Ray is an Enum(eration) */ + export namespace Enum { + + export const Impl = >(...values: T): Enum => { + return Object.fromEntries(values.map(value => + [value, Ray.Function.None.Impl((): Ray.Any => { + throw new NotImplementedError(); // TODO + })] + )) as Enum; + // TODO: ONE OF 4 SELECTION RAY for the case of type. + } - /** - * This is basically what breaks the recursive structure. - * - * Tries for "global coherence", practically this just means self-reference, were no change is (inconsistently) assumed... - * - * --- - * - * Another way of interpreting a possible way of implementing it, is no matter how much more detail we would like to ask, the only thing we ever see is the same structure again (if we ignore the difference of us asking about that additional structure, that's still a possible handle on some difference). - * - * As a way of saying/.../assuming: I only 'infinitely' assume it's only this structure, "it seems to halt here". Note that this is necessarily an assumption. No guarantee of this can be made. This is necessarily an equivalence, ..., ignorance. - * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. - */ - export const is_none = JS.Function.Self.Impl( - self => self.is_orbit(self.dereference()) - ); - export const is_some = JS.Function.Self.Impl( - self => self.is_none().not() - ); + } + /** Ray is a function (.next) */ + export namespace Function { - /** - * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. - * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. - */ - export const is_orbit = JS.Function.Self.Binary(Op.Binary.IS_ORBIT); + /** {T} is just an example/desired use case. But it generalizes to any function. */ + export type Type = T | Ray.Any; - export const self_reference = JS.Function.Self.Impl( - self => self - ); + /** From which perspective the Function is implemented. */ + enum Perspective { None, Self, /** Ref, */ } // TODO Ray.Enum? or not. - // TODO: set = none; - // TODO: Destroy the current thing, connect .initial & .terminal ? (can do just direct connection, preserves 'could have been something here') - then something like [self.initial, self, self.terminal].pop(). - // TODO: Leave behind --] [-- or connect them basically.. + // /** + // * Implement a function from the perspective of 'this' for 'this.self'. + // */ + // // static Ref = (impl: (ref: Ray.Any) => TResult): Function => Ray.Function.Self(self => impl(self.as_reference())); - // @alias('destroy', 'clear', 'delete', 'pop') - export const none = JS.Function.Self.Impl( // TODO FROM REF SPEC? - self => self.self = Op.New.NONE // TODO self: self_reference - ); + // // static CachedAfterUse = (constructor: FunctionConstructor): FunctionConstructor => { + // // return constructor; + // // } - /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ - export const terminal = JS.Function.Self.Impl(Op.Unary.TERMINAL); - /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ - export const initial = JS.Function.Self.Impl(Op.Unary.INITIAL); - /** - * An arbitrary Ray, defining what our current position is equivalent to. - * - * Moving to the intersecting Ray at `.self` - as a way of going an abstraction layer (lower), and asking what's inside. - */ - // @alias('dereference', 'self') - export const dereference = JS.Function.Self.Impl(Op.Unary.SELF); - export const self = dereference; - /** - * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. - * - * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) - */ - export const reference = JS.Function.Self.Impl( - self => Rays.New({ self: self }) - ); + /** Implement a function from no (or: an ignorant) perspective. */ + export namespace None { - /** - * @see "Continuations as Equivalence (can often be done in parallel - not generally)": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence - */ - // @alias('merge, 'continues_with', 'compose') - export const compose = JS.Function.Self.Binary( - (a, b) => a.terminal().equivalent(b.initial()) - ); + export const Impl = (impl: () => Ray.Any): Ray.Any => { + throw new NotImplementedError(); + // return new Ray.Any({ perspective: Perspective.None, impl }); + } - // @alias('modular', 'modulus', 'orbit') - export const orbit = JS.Function.Self.Binary( - (a, b) => a.first().initial().compose(b.last().terminal()) - ); + } - /** - * Equivalence as "Composition of Rays." - * - * NOTE: - * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. And it is expensive work to edge towards global coherence. - * - Though changes are only applied locally, their effects can be global (Take for instance, the example of adding to one Ray, which changes the perspective of everything connected to that Ray if they were to traverse the connection). - * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies - */ - export const equivalent = JS.Function.Self.Binary( - (a, b) => { - // throw new NotImplementedError(); + /** Implement a function from the perspective of 'this' */ + export namespace Self { + export const Impl = (impl: Ray.Op.Unary | ((self: Ray.Any) => Ray.Any)): Ray.Any => { + throw new NotImplementedError(); + // return new Ray.Any({ perspective: Perspective.Self, impl }); + } - // TODO: This is close but not quite, use the shifting thing I wrote down a few days ago: (And then use something to break the self-reference) - Either on this side. compose, or outside the definitions - // This one harder to do in parallel? - return a.self().compose(b.self()); - }); + export const Binary = (impl: Ray.Op.Binary | ((a: Ray.Any, b: Ray.Any) => Ray.Any)): Ray.Any => { + throw new NotImplementedError(); + // return new Ray.Any({ perspective: Perspective.Self, impl }); // TODO: Good way to deal with arity + } + + export const If = (impl: (self: Ray.Any) => Ray.Any): Ray.Any => { + return Impl(impl); // TODO: GENERIC collapse to boolean implemented and overridable + } + + export type MatchCase = [ + Function.Type, + Function.Type + ]; + + export type MatchCases = [...MatchCase[], /** 'else, ... default' **/ Function.Type]; + + /** + * TODO: + * - Maybe replace switch with 'zip'?, What are the practical differences? + */ + export const Match = (cases: MatchCases): Ray.Any => { + return Impl(self => self); // TODO + } + } - /** - * If there exists an orbit between A & B, anywhere (so dually connected, what if only one is aware??). - */ - // @alias('includes', 'contains') ; (slightly different variants?) - export const is_equivalent = JS.Function.Self.Binary( - (a, b) => a.self().traverse().is_orbit(b.self().traverse()) // Basically: does there exist a single connection between the two? - ); + export const Get = ( + property: TProperty + ): (typeof Ray.Function.All)[TProperty] | undefined => Ray.Function.All[property as TProperty] ?? undefined; + + export namespace All { + + /** [ |-?] */ export const is_initial = Ray.Function.Self.Impl( + self => self.initial().is_none() + ); + /** [--|--] */ export const is_vertex = Ray.Function.Self.Impl( + self => self.is_initial().nor(self.is_terminal()) + ); + /** [?-| ] */ export const is_terminal = Ray.Function.Self.Impl( + self => self.terminal().is_none() + ); + /** [ | ] */ export const is_reference = Ray.Function.Self.Impl( + self => self.is_initial().and(self.is_terminal()) + ); + /** [?-| ] or [ |-?] */ export const is_boundary = Ray.Function.Self.Impl( + self => self.is_initial().xor(self.is_terminal()) + ); + + export const type = Ray.Function.Self.Match([ + /** [ | ] */ [is_reference, Ray.Type.REFERENCE], + /** [ |-?] */ [is_initial, Ray.Type.INITIAL], + /** [?-| ] */ [is_terminal, Ray.Type.TERMINAL], + /** [--|--] */ Ray.Type.VERTEX + ]); + + /** + * This is basically what breaks the recursive structure. + * + * Tries for "global coherence", practically this just means self-reference, were no change is (inconsistently) assumed... + * + * --- + * + * Another way of interpreting a possible way of implementing it, is no matter how much more detail we would like to ask, the only thing we ever see is the same structure again (if we ignore the difference of us asking about that additional structure, that's still a possible handle on some difference). + * + * As a way of saying/.../assuming: I only 'infinitely' assume it's only this structure, "it seems to halt here". Note that this is necessarily an assumption. No guarantee of this can be made. This is necessarily an equivalence, ..., ignorance. + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. + */ + export const is_none = Ray.Function.Self.Impl( + self => self.is_orbit(self.dereference()) + ); + export const is_some = Ray.Function.Self.Impl( + self => self.is_none().not() + ); + + /** + * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. + */ + export const is_orbit = Ray.Function.Self.Binary(Op.Binary.IS_ORBIT); + + export const self_reference = Ray.Function.Self.Impl( + self => self + ); + + // TODO: set = none; + // TODO: Destroy the current thing, connect .initial & .terminal ? (can do just direct connection, preserves 'could have been something here') - then something like [self.initial, self, self.terminal].pop(). + // TODO: Leave behind --] [-- or connect them basically.. + + // @alias('destroy', 'clear', 'delete', 'pop') + export const none = Ray.Function.Self.Impl( // TODO FROM REF SPEC? + self => self.self = Op.New.NONE // TODO self: self_reference + ); + + /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ + export const terminal = Ray.Function.Self.Impl(Op.Unary.TERMINAL); + /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ + export const initial = Ray.Function.Self.Impl(Op.Unary.INITIAL); + /** + * An arbitrary Ray, defining what our current position is equivalent to. + * + * Moving to the intersecting Ray at `.self` - as a way of going an abstraction layer (lower), and asking what's inside. + */ + // @alias('dereference', 'self') + export const dereference = Ray.Function.Self.Impl(Op.Unary.SELF); + export const self = dereference; + + /** + * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. + * + * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) + */ + export const reference = Ray.Function.Self.Impl( + self => Ray.New({ self: self }) + ); + + /** + * @see "Continuations as Equivalence (can often be done in parallel - not generally)": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence + */ + // @alias('merge, 'continues_with', 'compose') + export const compose = Ray.Function.Self.Binary( + (a, b) => a.terminal().equivalent(b.initial()) + ); + + // @alias('modular', 'modulus', 'orbit') + export const orbit = Ray.Function.Self.Binary( + (a, b) => a.first().initial().compose(b.last().terminal()) + ); + + /** + * Equivalence as "Composition of Ray." + * + * NOTE: + * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. And it is expensive work to edge towards global coherence. + * - Though changes are only applied locally, their effects can be global (Take for instance, the example of adding to one Ray, which changes the perspective of everything connected to that Ray if they were to traverse the connection). + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies + */ + export const equivalent = Ray.Function.Self.Binary( + (a, b) => { + // throw new NotImplementedError(); + + // TODO: This is close but not quite, use the shifting thing I wrote down a few days ago: (And then use something to break the self-reference) - Either on this side. compose, or outside the definitions + // This one harder to do in parallel? + return a.self().compose(b.self()); + }); + + /** + * If there exists an orbit between A & B, anywhere (so dually connected, what if only one is aware??). + */ + // @alias('includes', 'contains') ; (slightly different variants?) + export const is_equivalent = Ray.Function.Self.Binary( + (a, b) => a.self().traverse().is_orbit(b.self().traverse()) // Basically: does there exist a single connection between the two? + ); + + export const traverse = Ray.Function.Self.Impl( + (a) => { throw new NotImplementedError(); } + ); + + + // TODO: .next but arbitrary step?? + export const next = Ray.Function.Self.Impl((self) => { + throw new NotImplementedError(); + return self; + }); + export const has_next = Ray.Function.Self.Impl((self) => self.next().is_some()); + // @alias('end', 'result', 'back', 'output') + export const last = Ray.Function.Self.Impl((self) => { + throw new NotImplementedError(); + return self; + }); + + export const previous = Ray.Function.Self.Impl((self) => self.not().next()); + // @alias() + export const has_previous = Ray.Function.Self.Impl((self) => self.not().has_next()); + // @alias('beginning', 'front') + export const first = Ray.Function.Self.Impl((self) => self.not().last()); + + // @alias('not', 'reverse', 'swap', 'converse', 'negative', 'neg') + // export const not = Ray.Function.Self.Impl(self => ); + // self.terminal = self.initial(); + // self.initial = self.terminal(); + // self.not().not() = self + // TODO: What's the difference in context between stepping after not / or not doing so. + // TODO; OR BINARY? - "It's just always .next from some perspective?" + // TODO: Level at which "not" is applied. + export const not = Ray.Function.Self.Binary((a, b) => b); + + export const and = Ray.Function.Self.Binary((a, b) => { throw new NotImplementedError(); + } ); + export const or = Ray.Function.Self.Binary((a, b) => { + throw new NotImplementedError(); + return self; + }); + export const xor = Ray.Function.Self.Binary((a, b) => a.xnor(b).not()); + export const xnor = Ray.Function.Self.Binary((a, b) => a.is_orbit(b)); // TODO: Could be 'is_equivalent' too? + export const nand = Ray.Function.Self.Binary((a, b) => a.and(b).not()); + export const nor = Ray.Function.Self.Binary((a, b) => a.or(b).not()); + + + // @alias(`push_{last.alias}`) + export const push_back = Ray.Function.Self.Binary( + (a, b) => a.last().compose(b) + ); + // @alias(`push_{first.alias}`) + export const push_front = Ray.Function.Self.Binary( + (a, b) => b.compose(a.first()) + ); + } + } - export const traverse = JS.Function.Self.Impl( - (a) => { throw new NotImplementedError(); } - ); + /** JavaScript runtime conversions */ + export const iterable = (iterable: Iterable): Ray.Any => Ray.iterator(iterable[Symbol.iterator]()); + export const async_iterable = (async_iterable: AsyncIterable): Ray.Any => Ray.async_iterator(async_iterable[Symbol.asyncIterator]()); + export const iterator = (iterator: Iterator): Ray.Any => { throw new NotImplementedError(); } + export const async_iterator = (async_iterator: AsyncIterator): Ray.Any => { throw new NotImplementedError(); } + export const generator = (generator: Generator): Ray.Any => Ray.iterator(generator); + export const async_generator = (generator: AsyncGenerator): Ray.Any => Ray.async_iterator(generator); + export const number = (number: number) => { throw new NotImplementedError(); } - // TODO: .next but arbitrary step?? - export const next = JS.Function.Self.Impl((self) => { - throw new NotImplementedError(); - return self; - }); - export const has_next = JS.Function.Self.Impl((self) => self.next().is_some()); - // @alias('end', 'result', 'back', 'output') - export const last = JS.Function.Self.Impl((self) => { - throw new NotImplementedError(); - return self; - }); - export const previous = JS.Function.Self.Impl((self) => self.not().next()); - // @alias() - export const has_previous = JS.Function.Self.Impl((self) => self.not().has_next()); - // @alias('beginning', 'front') - export const first = JS.Function.Self.Impl((self) => self.not().last()); - - // @alias('not', 'reverse', 'swap', 'converse', 'negative', 'neg') - // export const not = JS.Function.Self.Impl(self => ); - // self.terminal = self.initial(); - // self.initial = self.terminal(); - // self.not().not() = self - // TODO: What's the difference in context between stepping after not / or not doing so. - // TODO; OR BINARY? - "It's just always .next from some perspective?" - // TODO: Level at which "not" is applied. - export const not = JS.Function.Self.Binary((a, b) => b); - - export const and = JS.Function.Self.Binary((a, b) => { throw new NotImplementedError(); - } ); - export const or = JS.Function.Self.Binary((a, b) => { - throw new NotImplementedError(); - return self; - }); - export const xor = JS.Function.Self.Binary((a, b) => a.xnor(b).not()); - export const xnor = JS.Function.Self.Binary((a, b) => a.is_orbit(b)); // TODO: Could be 'is_equivalent' too? - export const nand = JS.Function.Self.Binary((a, b) => a.and(b).not()); - export const nor = JS.Function.Self.Binary((a, b) => a.or(b).not()); + /** TODO: Shouldn't classify these? */ + export const Type = Ray.Enum.Impl('REFERENCE', 'INITIAL', 'TERMINAL', 'VERTEX'); + // export const Boundary = { INITIAL: Type.INITIAL, TERMINAL: Type.TERMINAL }; TODO: LIST O - // @alias(`push_{last.alias}`) - export const push_back = JS.Function.Self.Binary( - (a, b) => a.last().compose(b) - ); - // @alias(`push_{first.alias}`) - export const push_front = JS.Function.Self.Binary( - (a, b) => b.compose(a.first()) - ); + // TODO CAN ALSO BE ZERO-ARY.. + // @alias('resize', 'size', 'structure', 'length', 'duplicate', 'copy') -> Should be generalized as any kind of structure, but with this thing repeated on it. ; use traversal or ... + export const size = Ray.Function.Self.Binary( + (a, size) => { throw new NotImplementedError(); } + ); + // @alias('bit') + // export const boolean = size(2); - } } -/** - * Other possibly names: "AbstractDirectionality, ..., ???" - * @alias - * @deprecated - */ -export type AbstractDirectionality = Ray; \ No newline at end of file +export default Ray; \ No newline at end of file diff --git a/src/@orbitmines/explorer/Ray2.ts b/src/@orbitmines/explorer/Ray2.ts index 4f8eea0..6b56115 100644 --- a/src/@orbitmines/explorer/Ray2.ts +++ b/src/@orbitmines/explorer/Ray2.ts @@ -10,7 +10,7 @@ export class Ray { // * [ |--] this.self ----- this.self.self [--|--] // * ______ (<- initial pointer) // */ - // as_initial = (): Ray => { + // as_initial = (): Ray.Any => { // if (this.is_none()) { // throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); // } @@ -43,7 +43,7 @@ export class Ray { * [ |--] this.self.self ----- this.self [--|--] * _____ (<- terminal pointer) */ - as_terminal = (): Ray => { + as_terminal = (): Ray.Any => { if (this.is_none()) { throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); } @@ -71,12 +71,12 @@ export class Ray { // TODO NOTE: THE ORDER OF `this.self` first matters here. return [this.self.___as_vertex(), this.___as_vertex()]; } - private ___as_vertex = (): Ray => { + private ___as_vertex = (): Ray.Any => { const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); return this.___ignorantly_equivalent(vertex); } - ___ignorantly_equivalent = (ref: Ray): Ray => { + ___ignorantly_equivalent = (ref: Ray.Any): Ray.Any => { ref.self.self = this.self.as_arbitrary(); this.self.self = ref.self.as_arbitrary(); @@ -84,7 +84,7 @@ export class Ray { } /** [ ] */ static None = () => new Ray({ }); - /** [--?--] */ static vertex = (value: JS.ParameterlessFunction = Ray.None) => { + /** [--?--] */ static vertex = (value: JS.ParameterlessFunction = Ray.None) => { /** [ ] */ const vertex = Ray.None(); /** [-- ] */ vertex.initial = vertex.___empty_initial(); /** [ ? ] */ vertex.vertex = value; @@ -92,18 +92,18 @@ export class Ray { /** [--?--] */ return vertex; } - /** [ |-?] */ static initial = () => Ray.vertex().initial; - /** [?-| ] */ static terminal = () => Ray.vertex().terminal; + /** [ |-?] */ static initial = () => Ray.Any.vertex().initial; + /** [?-| ] */ static terminal = () => Ray.Any.vertex().terminal; // TODO; Temp placeholders for now - & BETTER DEBUG - ___empty_initial = () => new Ray({ vertex: Ray.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); - ___empty_terminal = () => new Ray({ vertex: Ray.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); + ___empty_initial = () => new Ray({ vertex: Ray.Any.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); + ___empty_terminal = () => new Ray({ vertex: Ray.Any.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? - static equivalent = JS.Function.Impl((initial, terminal) => { + static equivalent = Ray.Function.Impl((initial, terminal) => { /** * The simplest case, is where both sides are only aware of themselves (on .vertex). The only thing we need to do is turn an Orbit, to an Orbit which repeats every 2 steps, the intermediate step being the other thing. @@ -114,7 +114,7 @@ export class Ray { * * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. */ - const ignorant_equivalence = (): Ray => { + const ignorant_equivalence = (): Ray.Any => { return initial.___ignorantly_equivalent(terminal); } @@ -188,14 +188,14 @@ export class Ray { static follow_direction = { - [RayType.INITIAL]: Ray.directions.next, - [RayType.TERMINAL]: Ray.directions.previous + [RayType.INITIAL]: Ray.Any.directions.next, + [RayType.TERMINAL]: Ray.Any.directions.previous } /** * .next */ - next = (step: JS.FunctionImpl = Ray.directions.next): Ray => { + next = (step: Ray.FunctionImpl = Ray.directions.next): Ray.Any => { if (step(this).self.self.is_none()) return Ray.None(); @@ -211,13 +211,13 @@ export class Ray { return Ray.None(); } // @alias('end', 'result', 'back') - last = (step: JS.FunctionImpl = Ray.directions.next): Ray => { + last = (step: Ray.FunctionImpl = Ray.directions.next): Ray.Any => { const next = this.next(step); return next.is_some() ? next.last(step) : this; } - get reverse(): Ray { + get reverse(): Ray.Any { const copy = this;//TODO.copy(); // TODO: Do we do this lazy by default? Just using refs??? - Or abstract this elsewhere to decide what to do @@ -229,7 +229,7 @@ export class Ray { return copy; } - *traverse(step: JS.FunctionImpl = Ray.directions.next): Generator { + *traverse(step: Ray.FunctionImpl = Ray.directions.next): Generator { // TODO: Also to ___func?? if (this.type !== RayType.VERTEX) @@ -240,7 +240,7 @@ export class Ray { *___next({ step = Ray.directions.next, - } = {}): Generator { + } = {}): Generator { for (let current of Ray.traverse({ initial: this.as_arbitrary(), step @@ -256,7 +256,7 @@ export class Ray { } } } - *___map(map: (vertex: Ray) => T, { + *___map(map: (vertex: Ray.Any) => T, { step = Ray.directions.next, } = {}): Generator { for (let vertex of this.___next({step})) { @@ -265,9 +265,9 @@ export class Ray { } static step_function = ( - step: JS.FunctionImpl - ): JS.Function => { - const step_from_boundary = (from: Ray, to: Ray): Ray => { + step: Ray.FunctionImpl + ): Ray.Function => { + const step_from_boundary = (from: Ray.Any, to: Ray.Any): Ray.Any => { switch (to.type) { /** * Dereferencing is likely in many cases quickly subject to infinite stepping (similar to INITIAL -> INITIAL, TERMINAL -> TERMINAL, VERTEX -> VERTEX. (Could be that this means that there's no continuation, a self-reference defined here, or it's some mechanism of halting.) @@ -322,7 +322,7 @@ export class Ray { && Ray.is_orbit(to.self, to.self.self.self) ) { // default pointer - // const default_pointer = (): Ray[] => { + // const default_pointer = (): Ray.Any[] => { // return pointer.terminal.is_none() ? [] : [pointer]; // } // TODO: Split of options.step(terminal) & new Ray({ @@ -338,7 +338,7 @@ export class Ray { } } - return JS.Function.WithMemory( + return Ray.Function.WithMemory( to_step => { const to = to_step.dereference; @@ -371,21 +371,21 @@ export class Ray { } static *traverse(options = { - initial: Ray.None, - step: Ray.directions.next, + initial: Ray.Any.None, + step: Ray.Any.directions.next, // branch: { // // @alias('pruning', 'mapping', 'filtering') - // prune: (branches: Ray): Ray => branches, + // prune: (branches: Ray.Any): Ray.Any => branches, // // @alias('next', 'selection', 'tactic', 'strategy') - // next: (branches: Ray): Ray => branches.first(), + // next: (branches: Ray.Any): Ray.Any => branches.first(), // } - }): Generator { + }): Generator { /** * An arbitrary Ray of (accessible) (possible) next steps to perform in traversal. */ // @alias('cursor(s)', 'branch(es)', 'selection(s)') - let branches: Ray = Ray.step_function(options.step).as_ray(options.initial()); // TODO; This can be used to copy? + let branches: Ray.Any = Ray.step_function(options.step).as_ray(options.initial()); // TODO; This can be used to copy? let branch = branches; while (true) { @@ -401,7 +401,7 @@ export class Ray { // /** // * An arbitrary Ray of (requested) next steps to perform in parallel/.../superposition (with respect to all the other branches). // */ - // const branches_to_traverse: Ray = options.branch.next(branches); + // const branches_to_traverse: Ray.Any = options.branch.next(branches); // // /** // * Make copies of our traversal for each selected branch @@ -412,7 +412,7 @@ export class Ray { // * Split off traversal to each branch, selecting their respective . // */ // - // let branch: Ray = branches_to_traverse; //TODO + // let branch: Ray.Any = branches_to_traverse; //TODO branch.self = branch.next().as_arbitrary(); @@ -434,7 +434,7 @@ export class Ray { * ref.self = branches[0].as_arbitrary(); * * if (branches.length !== 1) { - * pointers.push(...branches.slice(1).map(b => Ray.vertex(b.as_arbitrary()))); + * pointers.push(...branches.slice(1).map(b => Ray.Any.vertex(b.as_arbitrary()))); * } * } */ @@ -450,10 +450,10 @@ export class Ray { * TODO: * - This needs something much smarter at some point... */ - all = (step: JS.FunctionImpl = Ray.directions.next): { [key: string | symbol]: Ray } & any => { - return new Proxy(this, { + all = (step: Ray.FunctionImpl = Ray.directions.next): { [key: string | symbol]: Ray.Any } & any => { + return new Proxy(this, { - get(self: Ray, p: string | symbol, receiver: any): any { + get(self: Ray.Any, p: string | symbol, receiver: any): any { // TODO: Could return arbitrary structure (or in other method than .all?) return self.___map(ref => ref.any[p], {step}); @@ -462,7 +462,7 @@ export class Ray { /** * Can't overload things like '-=' for anything but things that return numbers... ; So just apply a general function instead. */ - set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { + set(self: Ray.Any, p: string | symbol, newValue: any, receiver: any): boolean { for (let ref of self.___next({step})) { // TODO; This needs to either be dynamically, or just a simple shut-off for circular ones. ref.any[p] = JS.is_function(newValue) ? newValue(ref.any[p]) : newValue; } @@ -471,7 +471,7 @@ export class Ray { }, - deleteProperty(self: Ray, p: string | symbol): boolean { + deleteProperty(self: Ray.Any, p: string | symbol): boolean { throw new NotImplementedError(); return true; @@ -484,22 +484,22 @@ export class Ray { /** * Move to a JavaScript object, which will handle any complexity of existing JavaScript objects, and allows one to abstract any values contained in the {vertex} to the usual JavaScript interface. - More usual to how one thinks about functions, ..., properties. */ - get any(): { [key: string | symbol]: Ray } & any { return this.self.proxy(); } - get ___any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } + get any(): { [key: string | symbol]: Ray.Any } & any { return this.self.proxy(); } + get ___any(): { [key: string | symbol]: Ray.Any } & any { return this.proxy(); } protected _proxy: any; protected _dirty_store: { [key: string | symbol]: object } = {} - protected proxy = (constructor?: JS.ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: + protected proxy = (constructor?: JS.ParameterlessConstructor): T & { [key: string | symbol]: Ray.Any } => { // TODO: // TODO: IMPLEMENT SPLAT... {...ray.any} - return this._proxy ??= new Proxy(this, { + return this._proxy ??= new Proxy(this, { - get(self: Ray, p: string | symbol, receiver: any): any { + get(self: Ray.Any, p: string | symbol, receiver: any): any { // throw new NotImplementedError(); return self._dirty_store[p]; // return self.as_arbitrary(); }, - set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { + set(self: Ray.Any, p: string | symbol, newValue: any, receiver: any): boolean { // TODO: // self._dirty_store[p] = JS.is_function(newValue) ? newValue(self._dirty_store[p]) : newValue; // throw new NotImplementedError(); @@ -508,7 +508,7 @@ export class Ray { return true; }, - deleteProperty(self: Ray, p: string | symbol): boolean { + deleteProperty(self: Ray.Any, p: string | symbol): boolean { if (!(p in self._dirty_store)) { return false; } @@ -529,7 +529,7 @@ export class Ray { * - Could lazily try to find references. * - Implement on proxy for 'delete ray' */ - delete = (): Ray => { + delete = (): Ray.Any => { this.self.initial = Ray.None; this.self.self = this.self.self_reference; this.self.terminal = Ray.None; @@ -543,7 +543,7 @@ export class Ray { return this; } - ___dirty_all(c: Ray[]): Ray[] { + ___dirty_all(c: Ray.Any[]): Ray.Any[] { if (c.filter(a => a.label === this.label).length !== 0) { return c; } diff --git a/src/@orbitmines/explorer/Visualization.tsx b/src/@orbitmines/explorer/Visualization.tsx index 98dbab4..11ae1c3 100644 --- a/src/@orbitmines/explorer/Visualization.tsx +++ b/src/@orbitmines/explorer/Visualization.tsx @@ -20,7 +20,7 @@ export type VisualizationProps = { alt: string, } -const Visualization = ({ray}: { ray: Ray }) => { +const Visualization = ({ray}: { ray: Ray.Any }) => { return diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/src/@orbitmines/explorer/debug/DebugCanvas.tsx index f1497fa..80353a1 100644 --- a/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -13,7 +13,7 @@ import _ from "lodash"; // TODO: It's, rende rboth draw equivalence, then ignore the difference from either perspective or take some middle thing. - Line from both ends, also vertex? (or take the pos, take the x from one/other, y from the other/..) // TODO: Could be a function on Ray (any func really) -export const Render = ({ ray, Interface }: { ray: Ray, Interface: Ray }) => { +export const Render = ({ ray, Interface }: { ray: Ray.Any, Interface: Ray.Any }) => { const initial: Required = ray.follow(Ray.directions.previous).render_options(Interface); const vertex: Required = ray.render_options(Interface); const terminal: Required = ray.follow().render_options(Interface); @@ -56,9 +56,9 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { const memory = false; - const [Interface] = useState(Ray.vertex().o({ - selection: Ray.vertex( - // () => Ray.vertex().o2({ + const [Interface] = useState(Ray.vertex().o({ + selection: Ray.Any.vertex( + // () => Ray.Any.vertex().o2({ // initial: { position: [-space_between, 0, 0], scale, rotation: [0, 0, Math.PI / 2] }, // vertex: { position: [0, 0, 0], scale, color: '#FF55FF' }, // terminal: { position: [space_between, 0, 0 ], scale, rotation: [0, 0, Math.PI / 2] } @@ -76,28 +76,28 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { rays: [] as Ray[], stats: false, cursor: { tick: false }, - controls: Ray.vertex().o({ + controls: Ray.Any.vertex().o({ hotkeys: [ { combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { - Interface.___any.selection = Interface.___any.selection.move((self: Ray) => self.initial, memory, Interface); + Interface.___any.selection = Interface.___any.selection.move((self: Ray.Any) => self.initial, memory, Interface); } }, { combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { - Interface.___any.selection = Interface.___any.selection.move((self: Ray) => self.terminal, memory, Interface); + Interface.___any.selection = Interface.___any.selection.move((self: Ray.Any) => self.terminal, memory, Interface); } }, { combo: ["delete"], global: true, label: "", onKeyDown: () => { - Interface.___any.rays = Interface.___any.rays.filter((ray: Ray) => ray.self.label !== Interface.___any.selection.self.label); // Should be automatic, this sort of thing + Interface.___any.rays = Interface.___any.Ray.filter((ray: Ray.Any) => Ray.Any.self.label !== Interface.___any.selection.self.label); // Should be automatic, this sort of thing Interface.___any.selection = Interface.___any.selection.delete; } }, { combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { // TODO SHOULD BE ANOTHER DIRECTION AT THE FRAME? - Interface.___any.selection = Interface.___any.selection.move((self: Ray) => self.self, memory, Interface); + Interface.___any.selection = Interface.___any.selection.move((self: Ray.Any) => self.self, memory, Interface); } }, { @@ -114,7 +114,7 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { { combo: ["space"], global: true, label: "", onKeyDown: (e) => { e.preventDefault(); - Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray.Any) => { ray.___any.traversed = true; return ray.as_reference(); }); @@ -122,27 +122,27 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { }, // { // combo: ["s", "arrowdown"], global: true, label: "", onKeyDown: () => { - // Interface.___any.selection = Interface.___any.selection.move((self: Ray) => self.as_reference().as_reference(), memory, Interface); + // Interface.___any.selection = Interface.___any.selection.move((self: Ray.Any) => self.as_reference().as_reference(), memory, Interface); // } // }, { combo: "/", global: true, label: "", onKeyDown: () => { console.log('---------') console.log(`Debugging: ${Interface.___any.selection.self.label} (type=${Interface.___any.selection.type})`) - console.log(`rays.length at pos=[${Interface.___any.selection.render_options.position}]: ${Interface.___any.rays.filter((ray: Ray) => + console.log(`Ray.length at pos=[${Interface.___any.selection.render_options.position}]: ${Interface.___any.Ray.filter((ray: Ray.Any) => _.isEqual( Interface.___any.selection.render_options.position, ray.render_options(Interface).position ) - ).length} / ${Interface.___any.rays.length}`) + ).length} / ${Interface.___any.Ray.length}`) console.log('ref', Interface.___any.selection) console.log('ref.self', Interface.___any.selection.self) const debug: DebugResult = {}; Interface.___any.selection.self.debug(debug); console.log('ref.debug', debug); - Interface.___any.rays.forEach((ray: Ray) => ray.debug(debug)); - console.log('rays.debug', debug); + Interface.___any.Ray.forEach((ray: Ray.Any) => Ray.Any.debug(debug)); + console.log('Ray.debug', debug); } }, @@ -166,8 +166,8 @@ export const DebugInterface = ({ scale = 1.5 }: InterfaceOptions) => { - {/*{Interface.___any.rays.map((ray: Ray) => )}*/} - {Interface.___any.rays.map((ray: Ray) => )} + {/*{Interface.___any.Ray.map((ray: Ray.Any) => )}*/} + {Interface.___any.Ray.map((ray: Ray.Any) => )} } diff --git a/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx b/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx index 0ff113c..64847c4 100644 --- a/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx +++ b/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx @@ -20,7 +20,7 @@ import {useThree} from "@react-three/fiber"; import {StatsPanels} from "./DebugCanvas"; import JS from "../JS"; -const ___index = (ray: Ray): number => { +const ___index = (ray: Ray.Any): number => { switch (ray.type) { case RayType.REFERENCE: return ray.___any.index ?? 0; @@ -33,7 +33,7 @@ const ___index = (ray: Ray): number => { } } -export const Render2 = ({ ray, Interface, show = { initial: true, terminal: true } }: { ray: Ray, Interface: Ray, index: number, show?: { initial: boolean, terminal: boolean } }) => { +export const Render2 = ({ ray, Interface, show = { initial: true, terminal: true } }: { ray: Ray.Any, Interface: Ray.Any, index: number, show?: { initial: boolean, terminal: boolean } }) => { const index = ___index(ray); let added = [15 * index, 60 * index, 0]; @@ -181,7 +181,7 @@ export const QuickVisualizationInterface = ({scale = 1.5}: InterfaceOptions) => const space_between = 20 * scale; - const [Interface] = useState(Ray.vertex().o({ + const [Interface] = useState(Ray.vertex().o({ selection: // The things selected Ray.None() @@ -199,9 +199,9 @@ export const QuickVisualizationInterface = ({scale = 1.5}: InterfaceOptions) => cursor: { tick: false }, - add: (ray: Ray) => { + add: (ray: Ray.Any) => { (Interface.any.selection as Ray).self.self = ray.self.as_arbitrary(); - Interface.any.rays.push(...[ray.follow(Ray.directions.previous), ray, ray.follow()]); + Interface.any.Ray.push(...[ray.follow(Ray.directions.previous), ray, ray.follow()]); }, controls: { hotkeys: [ @@ -350,14 +350,14 @@ export const QuickVisualizationInterface = ({scale = 1.5}: InterfaceOptions) => // TODO Then expand these to any-dimensional ]; const isFollowing = directions.map( - ([initial, terminal]): JS.FunctionImpl => { + ([initial, terminal]): Ray.FunctionImpl => { const toInitial = initial.some(option => pressed.includes(option)); const toTerminal = terminal.some(option => pressed.includes(option)); if (toInitial === toTerminal) return Ray.directions.none; - return toInitial ? Ray.directions.previous : Ray.directions.next; + return toInitial ? Ray.directions.previous : Ray.Any.directions.next; } ); @@ -379,23 +379,23 @@ export const QuickVisualizationInterface = ({scale = 1.5}: InterfaceOptions) => }, { combo: "/", global: true, label: "", preventDefault: true, onKeyDown: () => { - console.log(Interface.any.rays.map((ray: Ray) => ray.render_options(Interface))) + console.log(Interface.any.Ray.map((ray: Ray.Any) => Ray.Any.render_options(Interface))) // console.log('---------') // console.log(`Debugging: ${Interface.any.selection.self.label} (type=${Interface.any.selection.type})`) - // console.log(`rays.length at pos=[${Interface.any.selection.render_options(Interface).position}]: ${Interface.any.rays.filter((ray: Ray) => + // console.log(`Ray.length at pos=[${Interface.any.selection.render_options(Interface).position}]: ${Interface.any.Ray.filter((ray: Ray.Any) => // _.isEqual( // Interface.any.selection.render_options.position, // ray.render_options(Interface).position // ) - // ).length} / ${Interface.any.rays.length}`) + // ).length} / ${Interface.any.Ray.length}`) // console.log('ref', Interface.any.selection) // console.log('ref.self', Interface.any.selection.self) // // const debug: DebugResult = {}; // Interface.any.selection.self.debug(debug); // console.log('ref.debug', debug); - // Interface.any.rays.forEach((ray: Ray) => ray.debug(debug)); - // console.log('rays.debug', debug); + // Interface.any.Ray.forEach((ray: Ray.Any) => Ray.Any.debug(debug)); + // console.log('Ray.debug', debug); } }, @@ -427,15 +427,15 @@ export const QuickVisualizationInterface = ({scale = 1.5}: InterfaceOptions) => color="#555555" /> - {/*{Interface.any.rays.map((ray: Ray) => )}*/} + {/*{Interface.any.Ray.map((ray: Ray.Any) => )}*/} - {Interface.any.rays.map((ray: Ray) => )} + {Interface.any.Ray.map((ray: Ray.Any) => )} {/**/} {/* */} {/* */} - {/* {Interface.any.rays.___map((ray: Ray, index: number) => )}*/} + {/* {Interface.any.Ray.___map((ray: Ray.Any, index: number) => )}*/} {/* */} {/**/} @@ -443,7 +443,7 @@ export const QuickVisualizationInterface = ({scale = 1.5}: InterfaceOptions) => {/* */} {/* */} - {/* {Interface.any.rays.___map((ray: Ray, index: number) => )}*/} + {/* {Interface.any.Ray.___map((ray: Ray.Any, index: number) => )}*/} {/* */} {/**/} diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/src/@orbitmines/external/chyp/Chyp.ts index c74030c..8c5f5d6 100644 --- a/src/@orbitmines/external/chyp/Chyp.ts +++ b/src/@orbitmines/external/chyp/Chyp.ts @@ -3,7 +3,7 @@ import {NotImplementedError} from "../../explorer/errors/errors"; import JS from "../../explorer/JS"; /** - * An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Rays. + * An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Ray. * * **What is this?, What are Rays?** * @@ -33,22 +33,22 @@ export namespace Chyp { } // Vertex.in_edges = Ray.initial - get in_edges(): Ray { return this.initial; } set in_edges(ray: JS.ParameterlessFunction) { this.initial = ray; } + get in_edges(): Ray.Any { return this.initial; } set in_edges(ray: JS.ParameterlessFunction) { this.initial = ray; } // Vertex.out_edges = Ray.terminal - get out_edges(): Ray { return this.terminal; } set out_edges(ray: JS.ParameterlessFunction) { this.terminal = ray; } + get out_edges(): Ray.Any { return this.terminal; } set out_edges(ray: JS.ParameterlessFunction) { this.terminal = ray; } } export type EData = Edge; export class Edge extends Ray { // Edge.source = Ray.initial - get source(): Ray { return this.initial; } set source(ray: JS.ParameterlessFunction) { this.initial = ray; } - get s(): Ray { return this.initial; } set s(ray: JS.ParameterlessFunction) { this.initial = ray; } + get source(): Ray.Any { return this.initial; } set source(ray: JS.ParameterlessFunction) { this.initial = ray; } + get s(): Ray.Any { return this.initial; } set s(ray: JS.ParameterlessFunction) { this.initial = ray; } // Edge.targets = Ray.terminal - get target(): Ray { return this.terminal; } set target(ray: JS.ParameterlessFunction) { this.terminal = ray; } - get t(): Ray { return this.terminal; } set t(ray: JS.ParameterlessFunction) { this.terminal = ray; } + get target(): Ray.Any { return this.terminal; } set target(ray: JS.ParameterlessFunction) { this.terminal = ray; } + get t(): Ray.Any { return this.terminal; } set t(ray: JS.ParameterlessFunction) { this.terminal = ray; } } @@ -74,10 +74,10 @@ export namespace Chyp { } // Match.domain = Ray.initial - get domain(): Ray { return this.initial; } set domain(ray: JS.ParameterlessFunction) { this.initial = ray; } + get domain(): Ray.Any { return this.initial; } set domain(ray: JS.ParameterlessFunction) { this.initial = ray; } // Match.codomain = Ray.terminal - get codomain(): Ray { return this.terminal; } set codomain(ray: JS.ParameterlessFunction) { this.terminal = ray; } + get codomain(): Ray.Any { return this.terminal; } set codomain(ray: JS.ParameterlessFunction) { this.terminal = ray; } } @@ -92,10 +92,10 @@ export namespace Chyp { } // Rule.lhs = Ray.initial - get lhs(): Ray { return this.initial; } set lhs(ray: JS.ParameterlessFunction) { this.initial = ray; } + get lhs(): Ray.Any { return this.initial; } set lhs(ray: JS.ParameterlessFunction) { this.initial = ray; } // Rule.rhs = Ray.terminal - get rhs(): Ray { return this.terminal; } set rhs(ray: JS.ParameterlessFunction) { this.terminal = ray; } + get rhs(): Ray.Any { return this.terminal; } set rhs(ray: JS.ParameterlessFunction) { this.terminal = ray; } /** * TODO: We can use the same implementation to rewrite where there's not necessarily a match between initial/terminal side of a rule. @@ -117,7 +117,7 @@ export namespace Chyp { name = this.property('name', ''); - override get reverse(): Ray { + override get reverse(): Ray.Any { // TODO remove this hacky thing - just tries to us -a / a const name = this.name.startsWith('-') ? this.name.substring(1) : `-${this.name}`; @@ -125,7 +125,7 @@ export namespace Chyp { return super.reverse.o({ name }); } - dpo = (match: Match): Ray => { + dpo = (match: Match): Ray.Any => { throw new NotImplementedError(); } @@ -142,13 +142,13 @@ export namespace Chyp { } // Graph.inputs = Ray.initial - get inputs(): Ray { return this.initial; } set inputs(ray: JS.ParameterlessFunction) { this.initial = ray; } - set_inputs = (ray: JS.ParameterlessFunction): Graph => { this.inputs = ray; return this; } - add_inputs = (ray: Ray): Graph => { this.inputs.compose(ray); return this; } + get inputs(): Ray.Any { return this.initial; } set inputs(ray: JS.ParameterlessFunction) { this.initial = ray; } + set_inputs = (ray: JS.ParameterlessFunction): Graph => { this.inputs = ray; return this; } + add_inputs = (ray: Ray.Any): Graph => { this.inputs.compose(ray); return this; } // Graph.inputs = Ray.terminal - get outputs(): Ray { return this.terminal; } set outputs(ray: JS.ParameterlessFunction) { this.terminal = ray; } - set_outputs = (ray: JS.ParameterlessFunction): Graph => { this.outputs = ray; return this; } - add_outputs = (ray: Ray): Graph => { this.outputs.compose(ray); return this; } + get outputs(): Ray.Any { return this.terminal; } set outputs(ray: JS.ParameterlessFunction) { this.terminal = ray; } + set_outputs = (ray: JS.ParameterlessFunction): Graph => { this.outputs = ray; return this; } + add_outputs = (ray: Ray.Any): Graph => { this.outputs.compose(ray); return this; } } diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/src/@orbitmines/external/chyp/ChypCanvas.tsx index aa11824..0d032f6 100644 --- a/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ b/src/@orbitmines/external/chyp/ChypCanvas.tsx @@ -63,7 +63,7 @@ import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; // ...({ // color, // scale: 1.5, -// // rotation: ray.type == RayType.REFERENCE ? [0, 0, Math.PI / 6] : [0, 0, 0], +// // rotation: Ray.Any.type == RayType.REFERENCE ? [0, 0, Math.PI / 6] : [0, 0, 0], // position: [ // group_x ?? group_index(ray.label) * 20 * 1.5, // // (index_in_group(ray.label) + group_index(ray.label) + (group_x ? 0: 1)) * 30 * 1.5, @@ -99,7 +99,7 @@ import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; // // const None = (options: InterfaceOptions) => (<_Continuation {...options} color="#AA0000" scale={1} />) // -// const Extreme = ({type}: { type: RayType.INITIAL | RayType.TERMINAL }) => { +// const Extreme = ({type}: { type: Ray.AnyType.INITIAL | RayType.TERMINAL }) => { // const options = type === RayType.INITIAL ? initial : terminal; // // switch (ray.type) { @@ -111,7 +111,7 @@ import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; // case type: { // return ; // } -// case (type === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL): { +// case (type === RayType.INITIAL ? RayType.TERMINAL : Ray.AnyType.INITIAL): { // return <> // } // } @@ -119,7 +119,7 @@ import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; // // return // -// +// // // // }))} @@ -131,7 +131,7 @@ import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; // // } -const ___index = (ray: Ray): number => { +const ___index = (ray: Ray.Any): number => { switch (ray.type) { case RayType.REFERENCE: return ray.___any.index ?? 0; @@ -144,7 +144,7 @@ const ___index = (ray: Ray): number => { } } -export const Render2 = ({ ray, Interface, show = { initial: true, terminal: true } }: { ray: Ray, Interface: Ray, index: number, show?: { initial: boolean, terminal: boolean } }) => { +export const Render2 = ({ ray, Interface, show = { initial: true, terminal: true } }: { ray: Ray.Any, Interface: Ray.Any, index: number, show?: { initial: boolean, terminal: boolean } }) => { const index = ___index(ray); let added = [15 * index, 60 * index, 0]; @@ -249,8 +249,8 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { const space_between = 20 * scale; - const [Interface] = useState(Ray.vertex().o({ - selection: Ray.vertex().o2({ + const [Interface] = useState(Ray.vertex().o({ + selection: Ray.Any.vertex().o2({ initial: { position: [-space_between, 0, 0], scale, color: 'orange' }, vertex: { index: 0, position: [0, 0, 0], scale, color: 'orange' }, terminal: { position: [space_between, 0, 0 ], scale, color: 'orange' }, @@ -280,7 +280,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { }); Interface.___any.selection = selection.compose(next); - Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray.Any) => { ray.___any.traversed = true; return ray.as_reference(); }); @@ -289,7 +289,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { }, { combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { - if (Interface.___any.rays.length === 0) + if (Interface.___any.Ray.length === 0) return; Interface.___any.selection = Interface.___any.selection.pop(); @@ -300,7 +300,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { position: add(Interface.___any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. - Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray.Any) => { ray.___any.traversed = true; return ray.as_reference(); }); @@ -315,7 +315,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { const { selection, rays } = Interface.___any; - Interface.___any.rays = rays.flatMap((ray: Ray) => [ + Interface.___any.rays = Ray.flatMap((ray: Ray.Any) => [ ray, // Ray.js("A").as_reference().o({ // // ...ray.o, @@ -323,7 +323,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { // }), // Ray.js("A").as_reference().o({ // // ...ray.o, - // position: ray.___any.position, + // position: Ray.Any.___any.position, // rotation: [0, 0, Math.PI / 2] // }), // Ray.js("A").as_reference().o({ @@ -346,20 +346,20 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { combo: "/", global: true, label: "", onKeyDown: () => { console.log('---------') console.log(`Debugging: ${Interface.___any.selection.self.label} (type=${Interface.___any.selection.type})`) - console.log(`rays.length at pos=[${Interface.___any.selection.render_options(Interface).position}]: ${Interface.___any.rays.filter((ray: Ray) => + console.log(`Ray.length at pos=[${Interface.___any.selection.render_options(Interface).position}]: ${Interface.___any.Ray.filter((ray: Ray.Any) => _.isEqual( Interface.___any.selection.render_options.position, ray.render_options(Interface).position ) - ).length} / ${Interface.___any.rays.length}`) + ).length} / ${Interface.___any.Ray.length}`) console.log('ref', Interface.___any.selection) console.log('ref.self', Interface.___any.selection.self) const debug: DebugResult = {}; Interface.___any.selection.self.debug(debug); console.log('ref.debug', debug); - Interface.___any.rays.forEach((ray: Ray) => ray.debug(debug)); - console.log('rays.debug', debug); + Interface.___any.Ray.forEach((ray: Ray.Any) => Ray.Any.debug(debug)); + console.log('Ray.debug', debug); } }, @@ -387,15 +387,15 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { - {/*{Interface.___any.rays.map((ray: Ray) => )}*/} + {/*{Interface.___any.Ray.map((ray: Ray.Any) => )}*/} - {Interface.___any.rays.map((ray: Ray) => )} + {Interface.___any.Ray.map((ray: Ray.Any) => )} - {Interface.___any.rays.map((ray: Ray, index: number) => )} + {Interface.___any.Ray.map((ray: Ray.Any, index: number) => )} @@ -403,7 +403,7 @@ export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { - {Interface.___any.rays.map((ray: Ray, index: number) => )} + {Interface.___any.Ray.map((ray: Ray.Any, index: number) => )} @@ -457,8 +457,8 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { const space_between = 20 * scale; - const [Interface] = useState(Ray.vertex().o({ - selection: Ray.vertex().o2({ + const [Interface] = useState(Ray.vertex().o({ + selection: Ray.Any.vertex().o2({ initial: { position: [-space_between, 0, 0], scale, color: 'orange' }, vertex: { index: 0, position: [0, 0, 0], scale, color: 'orange' }, terminal: { position: [space_between, 0, 0 ], scale, color: 'orange' }, @@ -491,7 +491,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { }); Interface.___any.selection = selection.compose(next); - Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray.Any) => { ray.___any.traversed = true; return ray.as_reference(); }); @@ -500,7 +500,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { }, { combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { - if (Interface.___any.rays.length === 0) + if (Interface.___any.Ray.length === 0) return; Interface.___any.selection = Interface.___any.selection.pop(); @@ -511,7 +511,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { position: add(Interface.___any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. - Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray) => { + Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray.Any) => { ray.___any.traversed = true; return ray.as_reference(); }); @@ -526,7 +526,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { const { selection, rays } = Interface.___any; - Interface.___any.rays = rays.flatMap((ray: Ray) => [ + Interface.___any.rays = Ray.flatMap((ray: Ray.Any) => [ ray, // Ray.js("A").as_reference().o({ // // ...ray.o, @@ -534,7 +534,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { // }), // Ray.js("A").as_reference().o({ // // ...ray.o, - // position: ray.___any.position, + // position: Ray.Any.___any.position, // rotation: [0, 0, Math.PI / 2] // }), // Ray.js("A").as_reference().o({ @@ -557,20 +557,20 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { combo: "/", global: true, label: "", onKeyDown: () => { console.log('---------') console.log(`Debugging: ${Interface.___any.selection.self.label} (type=${Interface.___any.selection.type})`) - console.log(`rays.length at pos=[${Interface.___any.selection.render_options(Interface).position}]: ${Interface.___any.rays.filter((ray: Ray) => + console.log(`Ray.length at pos=[${Interface.___any.selection.render_options(Interface).position}]: ${Interface.___any.Ray.filter((ray: Ray.Any) => _.isEqual( Interface.___any.selection.render_options(Interface).position, ray.render_options(Interface).position ) - ).length} / ${Interface.___any.rays.length}`) + ).length} / ${Interface.___any.Ray.length}`) console.log('ref', Interface.___any.selection) console.log('ref.self', Interface.___any.selection.self) const debug: DebugResult = {}; Interface.___any.selection.self.debug(debug); console.log('ref.debug', debug); - Interface.___any.rays.forEach((ray: Ray) => ray.debug(debug)); - console.log('rays.debug', debug); + Interface.___any.Ray.forEach((ray: Ray.Any) => Ray.Any.debug(debug)); + console.log('Ray.debug', debug); } }, { @@ -602,14 +602,14 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { - {Interface.___any.rays.map((ray: Ray) => )} + {Interface.___any.Ray.map((ray: Ray.Any) => )} } // const Interface = () => { // // TODO: Direct call to rerender on change, now there's lag // -// const Rendered = ({ ray, ...options }: { ray: Ray } & InterfaceOptions) => { +// const Rendered = ({ ray, ...options }: { ray: Ray.Any } & InterfaceOptions) => { // const { position = options.position, rotation = options.rotation, scale = options.scale, color = options.color } = ray.___any; // return ; // } @@ -632,7 +632,7 @@ export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { // // // -// {rays.map((ray: Ray) => )} +// {Ray.map((ray: Ray.Any) => )} // // {/**/} //
diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts index 1ffa788..52d3057 100644 --- a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts +++ b/src/@orbitmines/external/chyp/Chyp_naive_pass.ts @@ -27,39 +27,39 @@ // * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" // */ // -// export const int = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const list = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Iterable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const str = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Optional = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QObject = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Union = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QWidget = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const List = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Qt = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Orientation = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QPainter = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const bool = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const False = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const True = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const editor = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Any = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const tuple = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const None = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const state = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Callable = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// export const Set = (t1?: any, t2?: any, t3?: any): Ray => { throw new NotImplementedError() }; -// -// export const Color = (t1: Ray = str('')): Ray => { throw new NotImplementedError() }; +// export const int = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const list = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const Iterable = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const set = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const str = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const Optional = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const Tuple = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QObject = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const Union = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QWidget = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const List = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const Qt = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const Orientation = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QPainter = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const bool = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const False = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const True = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const editor = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const Any = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const tuple = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const None = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const state = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const Callable = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// export const Set = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; +// +// export const Color = (t1: Ray.Any = str('')): Ray.Any => { throw new NotImplementedError() }; // // export class ValueError extends Error {} // @@ -108,12 +108,12 @@ // /** // * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. // */ -// get in_indices(): Ray { return this.initial } // -// get out_indices(): Ray { throw new NotImplementedError(); } +// get in_indices(): Ray.Any { return this.initial } // +// get out_indices(): Ray.Any { throw new NotImplementedError(); } // -// is_input = (): Ray => this.in_indices.count.as_int() > 0; -// is_output = (): Ray => this.out_indices.count.as_int() > 0; -// is_boundary = (): Ray => this.is_input() || this.is_output(); +// is_input = (): Ray.Any => this.in_indices.count.as_int() > 0; +// is_output = (): Ray.Any => this.out_indices.count.as_int() > 0; +// is_boundary = (): Ray.Any => this.is_input() || this.is_output(); // // // TODO: Probably generalizable // @@ -122,7 +122,7 @@ // * // * TODO; particular sort of composing // */ -// merge = (other: VData): Ray => { +// merge = (other: VData): Ray.Any => { // throw new NotImplementedError(); // } // @@ -135,7 +135,7 @@ // } // // // TODO: Shouldn't be here, this should be implemented on Ray if it's general enough -// get domain(): Ray { return JS.Iterable([this.vtype, this.size]) }; +// get domain(): Ray.Any { return JS.Iterable([this.vtype, this.size]) }; // // } // @@ -150,7 +150,7 @@ // hyper = this.property('value', bool(True)) // value = this.property('value') // -// __repr__ = (): Ray => { throw new NotImplementedError(); +// __repr__ = (): Ray.Any => { throw new NotImplementedError(); // // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' // } // @@ -162,10 +162,10 @@ // * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. // * - Otherwise draw as a larger (size 2) box. // */ -// box_size = (): Ray => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); +// box_size = (): Ray.Any => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); // -// domain = (): Ray => this.source.cast().domain; -// codomain = (): Ray => this.target.cast().domain; +// domain = (): Ray.Any => this.source.cast().domain; +// codomain = (): Ray.Any => this.target.cast().domain; // // toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL // } @@ -186,8 +186,8 @@ // */ // export class Graph extends Ray { // -// get vindex(): Ray { return this.vdata.index.max(0); } -// get eindex(): Ray { return this.edata.index.max(0); } +// get vindex(): Ray.Any { return this.vdata.index.max(0); } +// get eindex(): Ray.Any { return this.edata.index.max(0); } // // // Mapping from integer identifiers of each vertex to its data. // vdata = this.property('vertices'); @@ -204,20 +204,20 @@ // * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. // */ // // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. -// get domain(): Ray { return this.inputs.cast().domain; }; +// get domain(): Ray.Any { return this.inputs.cast().domain; }; // // /** // * Return the domain of the graph. // * // * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. // */ -// get codomain(): Ray { return this.outputs.cast().domain; }; +// get codomain(): Ray.Any { return this.outputs.cast().domain; }; // // vertex_data = (v = int): VData => this.vertices().at(v).cast(); // edge_data = (e = int): EData => this.edges().at(e).cast(); // // // TODO: Shouldnt be here -// ___next_index = (name = int(-1), index: Ray): Ray => { +// ___next_index = (name = int(-1), index: Ray.Any): Ray.Any => { // // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) // const current = name === -1 ? index : Math.max(name, index); // return current + 1; @@ -256,7 +256,7 @@ // // return edge; // } -// // add_simple_edge - is automatically handled: Rays can disambiguate between one/multiple values for certain purposes. +// // add_simple_edge - is automatically handled: Ray.Anys can disambiguate between one/multiple values for certain purposes. // // /** // * Remove a vertex from the graph. @@ -268,7 +268,7 @@ // * @param v // * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. // */ -// remove_vertex = (v = int, strict: boolean = false): Ray => { +// remove_vertex = (v = int, strict: boolean = false): Ray.Any => { // // TODO: as delegation // // if (strict) { @@ -293,7 +293,7 @@ // * // * @param e Integer identifier of the edge to remove. // */ -// remove_edge = (e = int): Ray => { +// remove_edge = (e = int): Ray.Any => { // // in/out edges from all vertices // delete this.edata[e]; // } @@ -318,7 +318,7 @@ // * Return vertices that lie on a directed path from any of `vs`. // * // TODO: Just traverse the rays, deduplicate using the index // */ -// successors = (ray: Ray): Ray => ray.next; +// successors = (ray: Ray.Any): Ray.Any => Ray.Any.next; // // /** // * Split a vertex into copies for each input, output, and tentacle. @@ -330,7 +330,7 @@ // * // * @param v Integer identifier of vertex to be exploded. // */ -// explode_vertex = (v = int): Ray => { +// explode_vertex = (v = int): Ray.Any => { // const vertex = this.vertex_data(v); // // // TODO; This just seems like another copy which minor changes @@ -340,8 +340,8 @@ // // const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process // vertex: VData, -// boundary: (vertex: VData) => Ray, -// next_boundary: Ray +// boundary: (vertex: VData) => Ray.Any, +// next_boundary: Ray.Any // ) => { // // TODO: It's just a duplicated process for vertex/edge since their definition is separataed // @@ -390,7 +390,7 @@ // * - If `False`, the original vertex becomes the source of the ew identity hyperedge while the new vertex becomes the target. // * - If `True`, the source and target of the new identity are flipped. This can be used to break directed cycles, by neffectively introducing a cap and cup. // */ -// insert_id_after = (v = int, reverse = bool(False)): Ray => { +// insert_id_after = (v = int, reverse = bool(False)): Ray.Any => { // const vertex = this.vertex_data(v); // // // Create a new vertex with the same vtype and size @@ -430,12 +430,12 @@ // * @param other // * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. // */ -// tensor = (other: Graph, layout: boolean = true): Ray => { +// tensor = (other: Graph, layout: boolean = true): Ray.Any => { // // const a = this; // const b = other; // -// const tensor: Ray = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] +// const tensor: Ray.Any = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] // // tensor.initial.any.y -= // tensor.initial.any.y.max(); // max_self @@ -459,7 +459,7 @@ // // /** // // * Compose structures defined at .initial with those at .terminal, dropping the vertex. ; or if done non-ignorantly. Composing them on another level, ignoring to this vertex. TODO: Allow this freedom // // */ -// // get merge(): Ray { +// // get merge(): Ray.Any { // // // concat initial.a + initial.b, terminal.a + terminal.b // // // then: either destroy a/b, merge structure... etc.. // // // Chyp: destroy b @@ -539,7 +539,7 @@ // * // * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. // */ -// compose = (other: Graph): Ray => { +// compose = (other: Graph): Ray.Any => { // // TODO Just matching outputs and inputs.. // // // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" @@ -632,7 +632,7 @@ // * // * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them // */ -// __mul__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.tensor(b)); +// __mul__ = (other: Graph): Ray.Any => this.___something_something_copy(other, (a, b) => a.tensor(b)); // // /** // * Return the composition of the current graph with `other`. @@ -640,12 +640,12 @@ // * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. // * @param other // */ -// __rshift__ = (other: Graph): Ray => this.___something_something_copy(other, (a, b) => a.compose(b)); +// __rshift__ = (other: Graph): Ray.Any => this.___something_something_copy(other, (a, b) => a.compose(b)); // // /** // * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer // */ -// ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray => { +// ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray.Any => { // const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. // something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? // return a_copy; // Could generalize to either end @@ -659,7 +659,7 @@ // * @param vertices A set of vertices to highlight. // * @param edges A set of edges to highlight. // */ -// highlight = (vertices = set(int), edges = set(int)): Ray => { +// highlight = (vertices = set(int), edges = set(int)): Ray.Any => { // // TODO Again, these could be merged // this.vdata // .filter(vertex => vertices.includes(vertex)) @@ -675,7 +675,7 @@ // * // * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. // */ -// unhighlight = (): Ray => { +// unhighlight = (): Ray.Any => { // // TODO: These could be merged // this.vdata.highlight = false; // this.edata.highlight = false; @@ -701,15 +701,15 @@ // // Try to find an initial match mapping one of the boundary vertices of the domain graph to the corresponding boundary vertex (the vertex in the same input/output location) of the codomain graph. If no initial match is found, return `None`. // const initial_match = new Match(this, other); // -// const ___temp = (func: (ray: Graph) => Ray) => { +// const ___temp = (func: (ray: Graph) => Ray.Any) => { // ([func(this), func(other)] as Ray).zip(([initial, terminal]) => { // if (!initial_match.try_add_vertex(initial, terminal)) // return None; //TODO, DOESNT ACTUALLY RETURN THE FUNCTION HERE. Wait till matcher is abstracted to fix this // }); // } // -// ___temp(ray => ray.inputs); -// ___temp(ray => ray.outputs); // TODO: See again, the same pattern over and over again, same on both sides. +// ___temp(ray => Ray.Any.inputs); +// ___temp(ray => Ray.Any.outputs); // TODO: See again, the same pattern over and over again, same on both sides. // // // If an initial match is found, try to find a total and surjective match of the domain graph into the codomain graph. // @@ -723,7 +723,7 @@ // } // // export class Chyp extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } +// __init__ = (): Ray.Any => { throw new NotImplementedError(); } // // /** // * Load a .chyp graph file from the given path. @@ -753,7 +753,7 @@ // } // // -// ___map_domain = (domain: Ray, _default: VData): Ray => { +// ___map_domain = (domain: Ray.Any, _default: VData): Ray.Any => { // return domain.map(([vtype, size], i) => { // const vertex: VData = _default.copy().cast(); // // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere @@ -771,7 +771,7 @@ // * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. // * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. // */ -// gen = (_default: VData, domain: Ray, codomain: Ray): Graph => { +// gen = (_default: VData, domain: Ray.Any, codomain: Ray.Any): Graph => { // const graph = new Graph(); // // const inputs = this.___map_domain(domain, _default) @@ -800,7 +800,7 @@ // * @param p A permutation given as an n-element list of integers from 0 to n-1. // * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. // */ -// perm = (p = list(int), domain: Ray, _default: VData) => { +// perm = (p = list(int), domain: Ray.Any, _default: VData) => { // // const graph = new Graph(); // const num_wires = p.count.as_int(); @@ -913,136 +913,136 @@ // } // // export class CodeView extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// popup_visible = (): Ray => { throw new NotImplementedError(); } -// set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } -// ident_at_cursor = (): Ray => { throw new NotImplementedError(); } -// insert_completion = (completion = str): Ray => { throw new NotImplementedError(); } -// keyPressEvent = (e = QKeyEvent): Ray => { throw new NotImplementedError(); } -// set_current_region = (region = Optional(Tuple(int,int))): Ray => { throw new NotImplementedError(); } -// add_line_below = (text = str): Ray => { throw new NotImplementedError(); } +// __init__ = (): Ray.Any => { throw new NotImplementedError(); } +// popup_visible = (): Ray.Any => { throw new NotImplementedError(); } +// set_completions = (completions = Iterable(str)): Ray.Any => { throw new NotImplementedError(); } +// ident_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } +// insert_completion = (completion = str): Ray.Any => { throw new NotImplementedError(); } +// keyPressEvent = (e = QKeyEvent): Ray.Any => { throw new NotImplementedError(); } +// set_current_region = (region = Optional(Tuple(int,int))): Ray.Any => { throw new NotImplementedError(); } +// add_line_below = (text = str): Ray.Any => { throw new NotImplementedError(); } // } // // export class CodeCompletionModel extends Ray { -// __init__ = (parent = QObject): Ray => { throw new NotImplementedError(); } -// set_completions = (completions = Iterable(str)): Ray => { throw new NotImplementedError(); } -// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } -// rowCount = (): Ray => { throw new NotImplementedError(); } +// __init__ = (parent = QObject): Ray.Any => { throw new NotImplementedError(); } +// set_completions = (completions = Iterable(str)): Ray.Any => { throw new NotImplementedError(); } +// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray.Any => { throw new NotImplementedError(); } +// rowCount = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class ChypDocument extends Ray { -// __init__ = (parent = QWidget): Ray => { throw new NotImplementedError(); } -// confirm_close = (): Ray => { throw new NotImplementedError(); } -// add_to_recent_files = (file_name = str): Ray => { throw new NotImplementedError(); } -// open = (file_name = str): Ray => { throw new NotImplementedError(); } -// save = (): Ray => { throw new NotImplementedError(); } -// save_as = (): Ray => { throw new NotImplementedError(); } +// __init__ = (parent = QWidget): Ray.Any => { throw new NotImplementedError(); } +// confirm_close = (): Ray.Any => { throw new NotImplementedError(); } +// add_to_recent_files = (file_name = str): Ray.Any => { throw new NotImplementedError(); } +// open = (file_name = str): Ray.Any => { throw new NotImplementedError(); } +// save = (): Ray.Any => { throw new NotImplementedError(); } +// save_as = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class Editor extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// title = (): Ray => { throw new NotImplementedError(); } -// reset_state = (): Ray => { throw new NotImplementedError(); } -// invalidate_text = (): Ray => { throw new NotImplementedError(); } -// next_part = (): Ray => { throw new NotImplementedError(); } -// jump_to_error = (): Ray => { throw new NotImplementedError(); } -// show_errors = (): Ray => { throw new NotImplementedError(); } -// show_at_cursor = (): Ray => { throw new NotImplementedError(); } -// next_rewrite_at_cursor = (): Ray => { throw new NotImplementedError(); } -// repeat_step_at_cursor = (): Ray => { throw new NotImplementedError(); } -// update_state = (): Ray => { throw new NotImplementedError(); } -// import_at_cursor = (): Ray => { throw new NotImplementedError(); } +// __init__ = (): Ray.Any => { throw new NotImplementedError(); } +// title = (): Ray.Any => { throw new NotImplementedError(); } +// reset_state = (): Ray.Any => { throw new NotImplementedError(); } +// invalidate_text = (): Ray.Any => { throw new NotImplementedError(); } +// next_part = (): Ray.Any => { throw new NotImplementedError(); } +// jump_to_error = (): Ray.Any => { throw new NotImplementedError(); } +// show_errors = (): Ray.Any => { throw new NotImplementedError(); } +// show_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } +// next_rewrite_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } +// repeat_step_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } +// update_state = (): Ray.Any => { throw new NotImplementedError(); } +// import_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class CheckThread extends Ray { -// __init__ = (rw = RewriteState): Ray => { throw new NotImplementedError(); } -// run = (): Ray => { throw new NotImplementedError(); } +// __init__ = (rw = RewriteState): Ray.Any => { throw new NotImplementedError(); } +// run = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class ErrorListModel extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// set_errors = (errors = List(Tuple(str, int, str))): Ray => { throw new NotImplementedError(); } -// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray => { throw new NotImplementedError(); } -// headerData = (section = int, orientation = Orientation): Ray => { throw new NotImplementedError(); } -// index = (row = int, column = int): Ray => { throw new NotImplementedError(); } -// columnCount = (): Ray => { throw new NotImplementedError(); } -// rowCount = (): Ray => { throw new NotImplementedError(); } -// parent = (): Ray => { throw new NotImplementedError(); } +// __init__ = (): Ray.Any => { throw new NotImplementedError(); } +// set_errors = (errors = List(Tuple(str, int, str))): Ray.Any => { throw new NotImplementedError(); } +// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray.Any => { throw new NotImplementedError(); } +// headerData = (section = int, orientation = Orientation): Ray.Any => { throw new NotImplementedError(); } +// index = (row = int, column = int): Ray.Any => { throw new NotImplementedError(); } +// columnCount = (): Ray.Any => { throw new NotImplementedError(); } +// rowCount = (): Ray.Any => { throw new NotImplementedError(); } +// parent = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class EItem extends Ray { -// __init__ = (g = Graph, e = int): Ray => { throw new NotImplementedError(); } -// paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray => { throw new NotImplementedError(); } +// __init__ = (g = Graph, e = int): Ray.Any => { throw new NotImplementedError(); } +// paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray.Any => { throw new NotImplementedError(); } // } // // export class VItem extends Ray { -// __init__ = (g = Graph, v = int): Ray => { throw new NotImplementedError(); } -// refresh = (): Ray => { throw new NotImplementedError(); } +// __init__ = (g = Graph, v = int): Ray.Any => { throw new NotImplementedError(); } +// refresh = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class TItem extends Ray { -// __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray => { throw new NotImplementedError(); } -// refresh = (): Ray => { throw new NotImplementedError(); } +// __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray.Any => { throw new NotImplementedError(); } +// refresh = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class GraphScene extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } -// add_items = (): Ray => { throw new NotImplementedError(); } -// mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } -// mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } -// mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray => { throw new NotImplementedError(); } +// __init__ = (): Ray.Any => { throw new NotImplementedError(); } +// set_graph = (g = Graph): Ray.Any => { throw new NotImplementedError(); } +// add_items = (): Ray.Any => { throw new NotImplementedError(); } +// mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray.Any => { throw new NotImplementedError(); } +// mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray.Any => { throw new NotImplementedError(); } +// mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray.Any => { throw new NotImplementedError(); } // } // // export class GraphView extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// set_graph = (g = Graph): Ray => { throw new NotImplementedError(); } +// __init__ = (): Ray.Any => { throw new NotImplementedError(); } +// set_graph = (g = Graph): Ray.Any => { throw new NotImplementedError(); } // } // // export class ChypHighlighter extends Ray { -// __init__ = (doc = QTextDocument): Ray => { throw new NotImplementedError(); } -// set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray => { throw new NotImplementedError(); } -// highlightBlock = (text = str): Ray => { throw new NotImplementedError(); } +// __init__ = (doc = QTextDocument): Ray.Any => { throw new NotImplementedError(); } +// set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray.Any => { throw new NotImplementedError(); } +// highlightBlock = (text = str): Ray.Any => { throw new NotImplementedError(); } // } // // export class MainWindow extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// remove_empty_editor = (): Ray => { throw new NotImplementedError(); } -// update_file_name = (): Ray => { throw new NotImplementedError(); } -// tab_changed = (i = int): Ray => { throw new NotImplementedError(); } -// update_themes = (): Ray => { throw new NotImplementedError(); } -// recent_files = (): Ray => { throw new NotImplementedError(); } -// update_recent_files = (): Ray => { throw new NotImplementedError(); } -// add_tab = (ed = Editor, title = str): Ray => { throw new NotImplementedError(); } -// close_tab = (): Ray => { throw new NotImplementedError(); } -// new = (): Ray => { throw new NotImplementedError(); } -// open = (): Ray => { throw new NotImplementedError(); } -// save = (): Ray => { throw new NotImplementedError(); } -// save_as = (): Ray => { throw new NotImplementedError(); } -// undo = (): Ray => { throw new NotImplementedError(); } -// redo = (): Ray => { throw new NotImplementedError(); } -// show_errors = (): Ray => { throw new NotImplementedError(); } -// add_rewrite_step = (): Ray => { throw new NotImplementedError(); } -// repeat_rewrite_step = (): Ray => { throw new NotImplementedError(); } -// next_rewrite = (): Ray => { throw new NotImplementedError(); } -// next_part = (): Ray => { throw new NotImplementedError(); } -// previous_part = (): Ray => { throw new NotImplementedError(); } -// next_tab = (): Ray => { throw new NotImplementedError(); } -// previous_tab = (): Ray => { throw new NotImplementedError(); } -// goto_import = (): Ray => { throw new NotImplementedError(); } -// closeEvent = (e = QCloseEvent): Ray => { throw new NotImplementedError(); } -// build_menu = (): Ray => { throw new NotImplementedError(); } +// __init__ = (): Ray.Any => { throw new NotImplementedError(); } +// remove_empty_editor = (): Ray.Any => { throw new NotImplementedError(); } +// update_file_name = (): Ray.Any => { throw new NotImplementedError(); } +// tab_changed = (i = int): Ray.Any => { throw new NotImplementedError(); } +// update_themes = (): Ray.Any => { throw new NotImplementedError(); } +// recent_files = (): Ray.Any => { throw new NotImplementedError(); } +// update_recent_files = (): Ray.Any => { throw new NotImplementedError(); } +// add_tab = (ed = Editor, title = str): Ray.Any => { throw new NotImplementedError(); } +// close_tab = (): Ray.Any => { throw new NotImplementedError(); } +// new = (): Ray.Any => { throw new NotImplementedError(); } +// open = (): Ray.Any => { throw new NotImplementedError(); } +// save = (): Ray.Any => { throw new NotImplementedError(); } +// save_as = (): Ray.Any => { throw new NotImplementedError(); } +// undo = (): Ray.Any => { throw new NotImplementedError(); } +// redo = (): Ray.Any => { throw new NotImplementedError(); } +// show_errors = (): Ray.Any => { throw new NotImplementedError(); } +// add_rewrite_step = (): Ray.Any => { throw new NotImplementedError(); } +// repeat_rewrite_step = (): Ray.Any => { throw new NotImplementedError(); } +// next_rewrite = (): Ray.Any => { throw new NotImplementedError(); } +// next_part = (): Ray.Any => { throw new NotImplementedError(); } +// previous_part = (): Ray.Any => { throw new NotImplementedError(); } +// next_tab = (): Ray.Any => { throw new NotImplementedError(); } +// previous_tab = (): Ray.Any => { throw new NotImplementedError(); } +// goto_import = (): Ray.Any => { throw new NotImplementedError(); } +// closeEvent = (e = QCloseEvent): Ray.Any => { throw new NotImplementedError(); } +// build_menu = (): Ray.Any => { throw new NotImplementedError(); } // } // // // TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? // export class Match extends Ray { // -// get vertex_map(): Ray { throw new NotImplementedError(); } -// get vertex_image(): Ray { throw new NotImplementedError(); } -// get edge_map(): Ray { throw new NotImplementedError(); } -// get edge_image(): Ray { throw new NotImplementedError(); } +// get vertex_map(): Ray.Any { throw new NotImplementedError(); } +// get vertex_image(): Ray.Any { throw new NotImplementedError(); } +// get edge_map(): Ray.Any { throw new NotImplementedError(); } +// get edge_image(): Ray.Any { throw new NotImplementedError(); } // -// __str__ = (): Ray => { +// __str__ = (): Ray.Any => { // // (f'\tVertex map: {str(self.vertex_map)}' // // + f'\n\tEdge map: {str(self.edge_map)}') // // TODO @@ -1050,7 +1050,7 @@ // // // Implemented on Ray // // TODO; doesnt copy the graphs at domain/codomain -// // copy = (): Ray => { throw new NotImplementedError(); } +// // copy = (): Ray.Any => { throw new NotImplementedError(); } // // /** // * Try to map `domain_vertex` to `codomain_vertex`. @@ -1059,7 +1059,7 @@ // * // * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. // */ -// try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray => { +// try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray.Any => { // // // If the vertex is already mapped, only check the new mapping is consistent with the current match. // if (this.vertex_map.includes(domain_vertex)) { @@ -1140,7 +1140,7 @@ // * // * `True` if a consistent match is found mapping `domain_edge` to `codomain_edge`, otherwise `False`. // */ -// try_add_edge = (initial: EData, terminal: EData): Ray => { +// try_add_edge = (initial: EData, terminal: EData): Ray.Any => { // log(`Trying to add edge ${initial} -> ${terminal} to match:`); // log(this.toString()); // @@ -1205,7 +1205,7 @@ // /** // * Return whether all adjacent edges of a domain vertex are mapped. // */ -// domain_neighbourhood_mapped = (vertex: VData): Ray => +// domain_neighbourhood_mapped = (vertex: VData): Ray.Any => // ([vertex.in_edges + vertex.out_edges] as Ray).all(edge => this.edge_map.includes(edge)); // // /** @@ -1222,11 +1222,11 @@ // * // * Returns: `True` if all scalars in the domain are mapped injectively to scalars in the codomain, otherwise `False`. // */ -// map_scalars = (): Ray => { +// map_scalars = (): Ray.Any => { // //TODO WHAT'S A SCALAR HERE? // // TODO: Again same pattern for (co)domain - flipped, two dimensional // const ___scalars = (domain: Graph, reverse: boolean) => { -// const is = (ray: Ray) => reverse ? ray.count !== 0 : ray.count === 0; // TODO: Should be easier to just .not this +// const is = (ray: Ray.Any) => reverse ? ray.count !== 0 : Ray.Any.count === 0; // TODO: Should be easier to just .not this // // return domain.edges // .filter((edge: EData) => this.is(edge.source) && this.is(edge.target)); @@ -1276,7 +1276,7 @@ // /** // * Return any matches extending `self` by a single vertex or edge. // */ -// more = (): Ray => { +// more = (): Ray.Any => { // // First, try to add an edge adjacent to any domain vertices that have already been matched. // this.vertex_map // // If all the edges adjacent to the current vertex have already been matched, continue. TODO: Could just be on the .vertex @@ -1285,7 +1285,7 @@ // // TODO: AS ZIp or something // const terminal_vertex = this.vertex_map[initial_vertex]; // -// const ___test = (boundary: (ray: Graph) => Ray): Ray => { +// const ___test = (boundary: (ray: Graph) => Ray.Any): Ray.Any => { // // Try to extend the match by mapping an adjacent source edge. // boundary(this.domain) // TODO: AGAIN SAME THING // // If the edge has already been matched, continue. @@ -1306,8 +1306,8 @@ // // } // -// ___test(ray => ray.in_edges); -// ___test(ray => ray.out_edges); +// ___test(ray => Ray.Any.in_edges); +// ___test(ray => Ray.Any.out_edges); // // }); // @@ -1340,16 +1340,16 @@ // /** // * Return whether all domain vertices and edges have been mapped. // */ -// is_total = (): Ray => this.___defuq('map', this.domain); +// is_total = (): Ray.Any => this.___defuq('map', this.domain); // /** // * Return whether the vertex and edge maps are surjective. // */ -// is_surjective = (): Ray => this.___defuq('image', this.codomain); +// is_surjective = (): Ray.Any => this.___defuq('image', this.codomain); // // /** // * Return whether the vertex and edge maps are injective. // */ -// is_injective = (): Ray => { +// is_injective = (): Ray.Any => { // // Since the edge map is always injective, we only need to check the vertex map is injective. TODO (GENERALIZE) // return this.vertex_map.count === this.vertex_image.count; // } @@ -1363,7 +1363,7 @@ // * // * TODO: Just no overlap?? // */ -// is_convex = (): Ray => { +// is_convex = (): Ray.Any => { // if (!this.is_injective()) { //TODO: WHY? // return false; // } @@ -1407,7 +1407,7 @@ // * stack and extending if possible until a valid match is found and returned. // */ // export class Matches extends Ray { -// __init__ = (domain = Graph, codomain = Graph): Ray => { +// __init__ = (domain = Graph, codomain = Graph): Ray.Any => { // /** // * TODO // * if initial_match is None: @@ -1424,14 +1424,14 @@ // * self.match_stack = [] // */ // throw new NotImplementedError(); } -// __iter__ = (): Ray => { throw new NotImplementedError(); } +// __iter__ = (): Ray.Any => { throw new NotImplementedError(); } // // /** // * Return the next suitable match found. // * // * A 'suitable' match is one that is total and, if `self.convex == True`, convex. // */ -// __next__ = (): Ray => { +// __next__ = (): Ray.Any => { // // TODO Like expected this, class can probably be dropped this just becomes // // return this.match_stack.dont_check_for_convex_or.is_convex; // TODO: Just generalize these on functions @@ -1464,13 +1464,13 @@ // // export class Rule extends Ray { // -// get equiv(): Ray { throw new NotImplementedError(); } +// get equiv(): Ray.Any { throw new NotImplementedError(); } // // // /** // * Returns True if boundary on lhs embeds injectively // */ -// is_left_linear = (): Ray => { +// is_left_linear = (): Ray.Any => { // // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading - Or should just equivalence a copy?? // return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() // .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. @@ -1482,7 +1482,7 @@ // * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. // * @param match // */ -// dpo = (match: Match): Ray => { +// dpo = (match: Match): Ray.Any => { // // if (!this.is_left_linear()) // // throw new NotImplementedError("Only left linear rules are supported for now") // @@ -1586,80 +1586,80 @@ // * // * This is a convenience wrapper for `dpo` for when the extra rewrite data isn't needed. // */ -// rewrite = (match: Match): Ray => this.dpo(match).first.terminal; // .first.codomain +// rewrite = (match: Match): Ray.Any => this.dpo(match).first.terminal; // .first.codomain // // TODO; Though .first is used here, something like .any is more appropriate in the sense of: Don't care which one first, just something. // } // // export class RewriteState extends Ray { -// __init__ = (sequence = int, state = State): Ray => { throw new NotImplementedError(); } -// check = (): Ray => { throw new NotImplementedError(); } +// __init__ = (sequence = int, state = State): Ray.Any => { throw new NotImplementedError(); } +// check = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class State extends Ray { -// __init__ = (): Ray => { throw new NotImplementedError(); } -// part_with_index_at = (pos = int): Ray => { throw new NotImplementedError(); } -// part_at = (pos = int): Ray => { throw new NotImplementedError(); } -// var = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// module_name = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// num = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// type_element = (items = list(Any)): Ray => { throw new NotImplementedError(); } -// type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray => { throw new NotImplementedError(); } -// id = (items = list(Any)): Ray => { throw new NotImplementedError(); } -// id0 = (_ = List(Any)): Ray => { throw new NotImplementedError(); } -// eq = (_ = List(Any)): Ray => { throw new NotImplementedError(); } -// le = (_ = List(Any)): Ray => { throw new NotImplementedError(); } -// perm_indices = (items = list(int)): Ray => { throw new NotImplementedError(); } -// size_list = (items = list(int)): Ray => { throw new NotImplementedError(); } -// par = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// gen_color = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// color = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// import_let = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// tactic = (items = List(Any)): Ray => { throw new NotImplementedError(); } -// nested_term = (items = List(Any)): Ray => { throw new NotImplementedError(); } +// __init__ = (): Ray.Any => { throw new NotImplementedError(); } +// part_with_index_at = (pos = int): Ray.Any => { throw new NotImplementedError(); } +// part_at = (pos = int): Ray.Any => { throw new NotImplementedError(); } +// var = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// module_name = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// num = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// type_element = (items = list(Any)): Ray.Any => { throw new NotImplementedError(); } +// type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray.Any => { throw new NotImplementedError(); } +// id = (items = list(Any)): Ray.Any => { throw new NotImplementedError(); } +// id0 = (_ = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// eq = (_ = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// le = (_ = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// perm_indices = (items = list(int)): Ray.Any => { throw new NotImplementedError(); } +// size_list = (items = list(int)): Ray.Any => { throw new NotImplementedError(); } +// par = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// gen_color = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// color = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// import_let = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// tactic = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } +// nested_term = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } // } // // export class Tactic extends Ray { -// __init__ = (local_state = RewriteState, args = List(str)): Ray => { throw new NotImplementedError(); } -// repeat = (rw = Callable([str], bool), rules = List(str)): Ray => { throw new NotImplementedError(); } -// error = (message = str): Ray => { throw new NotImplementedError(); } -// has_goal = (): Ray => { throw new NotImplementedError(); } -// global_rules = (): Ray => { throw new NotImplementedError(); } -// lookup_rule = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// add_refl_to_context = (graph = Graph, ident = str): Ray => { throw new NotImplementedError(); } -// add_rule_to_context = (rule_name = str): Ray => { throw new NotImplementedError(); } -// __lhs = (target = str): Ray => { throw new NotImplementedError(); } -// __rhs = (target = str): Ray => { throw new NotImplementedError(); } -// __set_lhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } -// __set_rhs = (target = str, graph = Graph): Ray => { throw new NotImplementedError(); } -// rewrite_lhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// rewrite_rhs = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// rewrite_lhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// rewrite_rhs1 = (rule_expr = str): Ray => { throw new NotImplementedError(); } -// validate_goal = (): Ray => { throw new NotImplementedError(); } -// lhs = (): Ray => { throw new NotImplementedError(); } -// rhs = (): Ray => { throw new NotImplementedError(); } -// lhs_size = (): Ray => { throw new NotImplementedError(); } -// rhs_size = (): Ray => { throw new NotImplementedError(); } -// highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } -// highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray => { throw new NotImplementedError(); } -// __reset = (): Ray => { throw new NotImplementedError(); } -// next_rhs = (current = str): Ray => { throw new NotImplementedError(); } -// run_check = (): Ray => { throw new NotImplementedError(); } -// name = (): Ray => { throw new NotImplementedError(); } -// check = (): Ray => { throw new NotImplementedError(); } -// make_rhs = (): Ray => { throw new NotImplementedError(); } +// __init__ = (local_state = RewriteState, args = List(str)): Ray.Any => { throw new NotImplementedError(); } +// repeat = (rw = Callable([str], bool), rules = List(str)): Ray.Any => { throw new NotImplementedError(); } +// error = (message = str): Ray.Any => { throw new NotImplementedError(); } +// has_goal = (): Ray.Any => { throw new NotImplementedError(); } +// global_rules = (): Ray.Any => { throw new NotImplementedError(); } +// lookup_rule = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } +// add_refl_to_context = (graph = Graph, ident = str): Ray.Any => { throw new NotImplementedError(); } +// add_rule_to_context = (rule_name = str): Ray.Any => { throw new NotImplementedError(); } +// __lhs = (target = str): Ray.Any => { throw new NotImplementedError(); } +// __rhs = (target = str): Ray.Any => { throw new NotImplementedError(); } +// __set_lhs = (target = str, graph = Graph): Ray.Any => { throw new NotImplementedError(); } +// __set_rhs = (target = str, graph = Graph): Ray.Any => { throw new NotImplementedError(); } +// rewrite_lhs = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } +// rewrite_rhs = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } +// rewrite_lhs1 = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } +// rewrite_rhs1 = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } +// validate_goal = (): Ray.Any => { throw new NotImplementedError(); } +// lhs = (): Ray.Any => { throw new NotImplementedError(); } +// rhs = (): Ray.Any => { throw new NotImplementedError(); } +// lhs_size = (): Ray.Any => { throw new NotImplementedError(); } +// rhs_size = (): Ray.Any => { throw new NotImplementedError(); } +// highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray.Any => { throw new NotImplementedError(); } +// highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray.Any => { throw new NotImplementedError(); } +// __reset = (): Ray.Any => { throw new NotImplementedError(); } +// next_rhs = (current = str): Ray.Any => { throw new NotImplementedError(); } +// run_check = (): Ray.Any => { throw new NotImplementedError(); } +// name = (): Ray.Any => { throw new NotImplementedError(); } +// check = (): Ray.Any => { throw new NotImplementedError(); } +// make_rhs = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class RuleTac extends Ray { -// name = (): Ray => { throw new NotImplementedError(); } -// make_rhs = (): Ray => { throw new NotImplementedError(); } -// check = (): Ray => { throw new NotImplementedError(); } +// name = (): Ray.Any => { throw new NotImplementedError(); } +// make_rhs = (): Ray.Any => { throw new NotImplementedError(); } +// check = (): Ray.Any => { throw new NotImplementedError(); } // } // // export class SimpTac extends Ray { -// name = (): Ray => { throw new NotImplementedError(); } -// __prepare_rules = (): Ray => { throw new NotImplementedError(); } -// make_rhs = (): Ray => { throw new NotImplementedError(); } -// check = (): Ray => { throw new NotImplementedError(); } +// name = (): Ray.Any => { throw new NotImplementedError(); } +// __prepare_rules = (): Ray.Any => { throw new NotImplementedError(); } +// make_rhs = (): Ray.Any => { throw new NotImplementedError(); } +// check = (): Ray.Any => { throw new NotImplementedError(); } // } // diff --git a/src/@orbitmines/external/chyp/README.md b/src/@orbitmines/external/chyp/README.md index ddcfbd3..15b77d3 100644 --- a/src/@orbitmines/external/chyp/README.md +++ b/src/@orbitmines/external/chyp/README.md @@ -1,4 +1,4 @@ -An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Rays. +An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Ray. **What is this?, What are Rays?** diff --git a/src/routes/papers/2023.OnOrbits.tsx b/src/routes/papers/2023.OnOrbits.tsx index c37d6b1..e59f455 100644 --- a/src/routes/papers/2023.OnOrbits.tsx +++ b/src/routes/papers/2023.OnOrbits.tsx @@ -2044,7 +2044,7 @@ const OnOrbits = () => {
- What I think this will turn out to be; Is that in the process of trying to understand programming languages, compilation and compression. That I ended up abstracting so far away from them. That aided by having some intuitive notion of hyperedges, I stumbled upon this formulation of Rays. + What I think this will turn out to be; Is that in the process of trying to understand programming languages, compilation and compression. That I ended up abstracting so far away from them. That aided by having some intuitive notion of hyperedges, I stumbled upon this formulation of Ray.
From 39ba5131a11642e8e3e1f7c801dbd2b47b4392bf Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 15:03:15 +0100 Subject: [PATCH 121/138] 2024/01/25 - Move everything to a separate orbitmines.com folder. --- .github/workflows/test.yml | 6 +- .gitignore | 9 +++ .npmrc => orbitmines.com/.npmrc | 0 Dockerfile => orbitmines.com/Dockerfile | 0 .../build}/asset-manifest.json | 0 {build => orbitmines.com/build}/favicon.png | Bin {build => orbitmines.com/build}/index.html | 0 {build => orbitmines.com/build}/logo.png | Bin {build => orbitmines.com/build}/manifest.json | 0 .../build}/papers/on-intelligibility.jpeg | Bin .../build}/papers/on-intelligibility.pdf | Bin .../build}/papers/sitemap.xml | 0 .../build}/profiles/fadi-shawki.jpeg | Bin .../build}/profiles/fadi-shawki.pdf | Bin .../profiles/fadi-shawki/profile-picture.jpg | Bin .../build}/profiles/sitemap.xml | 0 {build => orbitmines.com/build}/robots.txt | 0 {build => orbitmines.com/build}/sitemap.xml | 0 .../build}/static/css/main.f3c29dcc.css | 0 .../build}/static/css/main.f3c29dcc.css.map | 0 ...ueprint-icons-16px-paths.e600f430.chunk.js | 0 ...int-icons-16px-paths.e600f430.chunk.js.map | 0 ...ueprint-icons-20px-paths.aea2767b.chunk.js | 0 ...int-icons-20px-paths.aea2767b.chunk.js.map | 0 ...t-icons-all-paths-loader.03d11c89.chunk.js | 0 ...ons-all-paths-loader.03d11c89.chunk.js.map | 0 ...lueprint-icons-all-paths.ebc06bc3.chunk.js | 0 ...rint-icons-all-paths.ebc06bc3.chunk.js.map | 0 ...lit-paths-by-size-loader.28faa981.chunk.js | 0 ...paths-by-size-loader.28faa981.chunk.js.map | 0 .../build}/static/js/main.a4bd6e59.js | 0 .../static/js/main.a4bd6e59.js.LICENSE.txt | 0 .../build}/static/js/main.a4bd6e59.js.map | 0 ...etBrainsMono-Bold.a490f58c0f460cdc1a8d.ttf | Bin ...rainsMono-Regular.73fb7b7f0e68b372adfe.ttf | Bin ...ainsMono-SemiBold.6c00e23bc7910a97f8e8.ttf | Bin ...on-circle-NGI-rgb.c187053ac056096e2c8f.png | Bin ...lueprint-icons-16.a06729235b0be3c89599.eot | Bin ...lueprint-icons-16.a3184b43073d6a13b0ff.svg | 0 ...lueprint-icons-16.e7a60f2ff401d5c92c24.ttf | Bin ...ueprint-icons-16.ed58254a5b3bcbb792c0.woff | Bin ...eprint-icons-16.f313e46860f341decc69.woff2 | Bin ...lueprint-icons-20.2417badadcf0d0550bf7.eot | Bin ...lueprint-icons-20.44fac984317ccf8ffc81.ttf | Bin ...lueprint-icons-20.6b3b37d0b8765e8789ad.svg | 0 ...eprint-icons-20.73d7a30f5fc31bef9177.woff2 | Bin ...ueprint-icons-20.8f34eccd1505822c8837.woff | Bin ...channels4_profile.fa1b005883d06175e760.jpg | Bin ...ines.icon.650x650.81a851f37d449e32d039.png | Bin ...es.logo.3000x1000.e3b652e472c9565f6f93.png | Bin .../media/semf_icon.074319a62dc1fe56a243.jpg | Bin ...r_no_year_square2.c44a51529852563fffb8.png | Bin .../topos_favicon.edde03404c314a2f6347.ico | Bin .../config-overrides.js | 0 .../package-lock.json | 0 package.json => orbitmines.com/package.json | 0 {public => orbitmines.com/public}/favicon.png | Bin {public => orbitmines.com/public}/index.html | 0 {public => orbitmines.com/public}/logo.png | Bin .../public}/manifest.json | 0 .../public}/papers/on-intelligibility.jpeg | Bin .../public}/papers/on-intelligibility.pdf | Bin ...rbits-equivalence-and-inconsistencies.jpeg | Bin ...orbits-equivalence-and-inconsistencies.pdf | Bin .../images/0_1.png | Bin .../images/0_1_tilted.png | Bin .../images/1_loop.png | Bin .../images/1_loop_2_select_1.png | Bin .../images/1_loop_expanded.png | Bin .../images/1_loop_selected.png | Bin .../images/2_2.png | Bin .../images/2_double_expanded_continuation.png | Bin .../images/2_edge.png | Bin .../images/2_edge_3_fractal.png | Bin .../images/2_edge_3_fractal_equived.png | Bin .../2_edge_3_fractal_equived_select_0.png | Bin ...3_fractal_equived_select_0_teleporting.png | Bin .../2_edge_3_fractal_equived_select_1.png | Bin ...3_fractal_equived_select_1_teleporting.png | Bin .../2_edge_3_fractal_equived_selected.png | Bin .../images/2_edge_3_fractal_with_equivs.png | Bin .../images/2_expanded_continuation.png | Bin .../2_expanded_continuation_selected.png | Bin .../images/2_horizontal_binary.png | Bin .../images/2_horizontal_binary_loops.png | Bin .../images/2_loop_2_select_1.png | Bin .../images/2_orange.png | Bin .../images/2_select_0.png | Bin .../images/2_select_1.png | Bin .../images/2_superposition.png | Bin .../images/2_vertical_binary.png | Bin .../images/2_vertical_pink.png | Bin .../images/3.png | Bin .../images/3_expanded_continuation.png | Bin .../images/3_fractal.png | Bin .../images/3_select_0.png | Bin .../images/3_tertiary.png | Bin .../images/4_bits.png | Bin .../images/4_bits_grid.png | Bin .../images/4_bits_seperated.png | Bin .../images/4_bits_unordered.png | Bin .../images/branch.png | Bin .../images/branch_expanded.png | Bin .../images/empty_vertex.png | Bin .../images/empty_vertex_green.png | Bin .../images/header.png | Bin .../images/naked_point.png | Bin .../images/some_structure.png | Bin .../images/thumbnail/1920x1080.jpeg | Bin .../images/thumbnail/3840x2160.jpeg | Bin .../images/two_vertices.png | Bin .../public}/papers/sitemap.xml | 0 .../public}/profiles/fadi-shawki.jpeg | Bin .../public}/profiles/fadi-shawki.pdf | Bin .../profiles/fadi-shawki/profile-picture.jpg | Bin .../public}/profiles/sitemap.xml | 0 {public => orbitmines.com/public}/robots.txt | 0 {public => orbitmines.com/public}/sitemap.xml | 0 .../src}/@orbitmines/explorer/JS.spec.ts | 0 .../src}/@orbitmines/explorer/JS.ts | 0 .../src}/@orbitmines/explorer/JS2.ts | 0 .../explorer/OrbitMinesExplorer.tsx | 0 .../REFACTOR_AFTER_WORKING_TRAVERSE.md | 0 .../@orbitmines/explorer/REFACTOR_RENDER.md | 0 .../src}/@orbitmines/explorer/Ray.spec.ts | 0 .../src}/@orbitmines/explorer/Ray.ts | 0 .../src}/@orbitmines/explorer/Ray2.ts | 0 .../@orbitmines/explorer/Visualization.tsx | 0 .../explorer/debug/DebugCanvas.tsx | 0 .../debug/QuickVisualizationInterface.tsx | 0 .../@orbitmines/explorer/errors/errors.ts | 0 .../@orbitmines/external/chyp/Chyp.spec.ts | 0 .../src}/@orbitmines/external/chyp/Chyp.ts | 0 .../@orbitmines/external/chyp/ChypCanvas.tsx | 0 .../external/chyp/Chyp_naive_pass.ts | 0 .../src}/@orbitmines/external/chyp/README.md | 0 .../@orbitmines/external/chyp/examples.ts | 0 .../@orbitmines/js/react/IEventListener.tsx | 0 .../src}/@orbitmines/js/react/IModule.ts | 0 .../src}/@orbitmines/js/react/Modules.tsx | 0 .../@orbitmines/js/react/hooks/useHotkeys.ts | 0 .../@orbitmines/js/react/hooks/useHovering.ts | 0 .../src}/@orbitmines/rays/index.ts | 0 {src => orbitmines.com/src}/App.tsx | 0 {src => orbitmines.com/src}/index.tsx | 0 {src => orbitmines.com/src}/lib/index.ts | 0 .../experimental-designs/BlueprintJS.tsx | 0 .../lib/layout/experimental-designs/Icons.tsx | 0 .../layout/experimental-designs/Legacy.tsx | 0 .../src}/lib/layout/flexbox/Col.tsx | 0 .../src}/lib/layout/flexbox/Grid.tsx | 0 .../src}/lib/layout/flexbox/Row.tsx | 0 .../src}/lib/layout/flexbox/constants.ts | 0 .../src}/lib/layout/flexbox/index.ts | 0 .../lib/layout/flexbox/styles/flexbox.scss | 0 .../src}/lib/layout/font/Font.tsx | 0 .../JetBrainsMono/JetBrainsMono-2.242.zip | Bin .../font/fonts/JetBrainsMono/JetBrainsMono.ts | 0 .../JetBrains Mono NL SemiBold_Italic.json | 0 .../JetBrains Mono NL SemiBold_Regular.json | 0 .../json/JetBrains Mono NL Thin_Italic.json | 0 .../json/JetBrains Mono NL Thin_Regular.json | 0 .../json/JetBrains Mono NL_Regular.json | 0 .../json/JetBrains Mono SemiBold_Italic.json | 0 .../json/JetBrains Mono SemiBold_Regular.json | 0 .../json/JetBrains Mono Thin_Italic.json | 0 .../json/JetBrains Mono Thin_Regular.json | 0 .../json/JetBrains Mono_Regular.json | 0 .../JetBrainsMono/ttf/JetBrainsMono-Bold.ttf | Bin .../ttf/JetBrainsMono-BoldItalic.ttf | Bin .../ttf/JetBrainsMono-ExtraBold.ttf | Bin .../ttf/JetBrainsMono-ExtraBoldItalic.ttf | Bin .../ttf/JetBrainsMono-ExtraLight.ttf | Bin .../ttf/JetBrainsMono-ExtraLightItalic.ttf | Bin .../ttf/JetBrainsMono-Italic.ttf | Bin .../JetBrainsMono/ttf/JetBrainsMono-Light.ttf | Bin .../ttf/JetBrainsMono-LightItalic.ttf | Bin .../ttf/JetBrainsMono-Medium.ttf | Bin .../ttf/JetBrainsMono-MediumItalic.ttf | Bin .../ttf/JetBrainsMono-Regular.ttf | Bin .../ttf/JetBrainsMono-SemiBold.ttf | Bin .../ttf/JetBrainsMono-SemiBoldItalic.ttf | Bin .../JetBrainsMono/ttf/JetBrainsMono-Thin.ttf | Bin .../ttf/JetBrainsMono-ThinItalic.ttf | Bin .../ttf/JetBrainsMonoNL-Bold.ttf | Bin .../ttf/JetBrainsMonoNL-BoldItalic.ttf | Bin .../ttf/JetBrainsMonoNL-ExtraBold.ttf | Bin .../ttf/JetBrainsMonoNL-ExtraBoldItalic.ttf | Bin .../ttf/JetBrainsMonoNL-ExtraLight.ttf | Bin .../ttf/JetBrainsMonoNL-ExtraLightItalic.ttf | Bin .../ttf/JetBrainsMonoNL-Italic.ttf | Bin .../ttf/JetBrainsMonoNL-Light.ttf | Bin .../ttf/JetBrainsMonoNL-LightItalic.ttf | Bin .../ttf/JetBrainsMonoNL-Medium.ttf | Bin .../ttf/JetBrainsMonoNL-MediumItalic.ttf | Bin .../ttf/JetBrainsMonoNL-Regular.ttf | Bin .../ttf/JetBrainsMonoNL-SemiBold.ttf | Bin .../ttf/JetBrainsMonoNL-SemiBoldItalic.ttf | Bin .../ttf/JetBrainsMonoNL-Thin.ttf | Bin .../ttf/JetBrainsMonoNL-ThinItalic.ttf | Bin .../variable/JetBrainsMono-Italic[wght].ttf | Bin .../variable/JetBrainsMono[wght].ttf | Bin .../webfonts/JetBrainsMono-Bold.woff2 | Bin .../webfonts/JetBrainsMono-BoldItalic.woff2 | Bin .../webfonts/JetBrainsMono-ExtraBold.woff2 | Bin .../JetBrainsMono-ExtraBoldItalic.woff2 | Bin .../webfonts/JetBrainsMono-ExtraLight.woff2 | Bin .../JetBrainsMono-ExtraLightItalic.woff2 | Bin .../webfonts/JetBrainsMono-Italic.woff2 | Bin .../webfonts/JetBrainsMono-Light.woff2 | Bin .../webfonts/JetBrainsMono-LightItalic.woff2 | Bin .../webfonts/JetBrainsMono-Medium.woff2 | Bin .../webfonts/JetBrainsMono-MediumItalic.woff2 | Bin .../webfonts/JetBrainsMono-Regular.woff2 | Bin .../webfonts/JetBrainsMono-SemiBold.woff2 | Bin .../JetBrainsMono-SemiBoldItalic.woff2 | Bin .../webfonts/JetBrainsMono-Thin.woff2 | Bin .../webfonts/JetBrainsMono-ThinItalic.woff2 | Bin .../src}/lib/layout/font/styles/font.scss | 0 .../src}/lib/layout/icons/CustomIcon.tsx | 0 .../blueprintjs/styles/blueprintjs.scss | 0 .../src}/lib/layout/styles/index.scss | 0 .../src}/lib/layout/styles/spacing.scss | 0 .../lib/organizations/3b1b/3B1B_Logo.svg.png | Bin .../src}/lib/organizations/ORGANIZATIONS.ts | 0 .../src}/lib/organizations/README.md | 0 .../lib/organizations/akissinger/881183.png | Bin .../critical-thinking/he8VyFCv_400x400.jpg | Bin ..._403b35d6-ec76-4cd9-a70d-bd1c5d825460.avif | Bin ...s_403b35d6-ec76-4cd9-a70d-bd1c5d825460.png | Bin .../discord/discord-mark-white.svg | 0 ...99fc1f178d48c7b9f775ed1f6b9a4ff5f851c2.svg | 0 .../lib/organizations/github/GitHub-Logos.zip | Bin .../GitHub-Logos/GitHub-Logos/GitHub_Logo.ai | 0 .../GitHub-Logos/GitHub-Logos/GitHub_Logo.eps | Bin .../GitHub-Logos/GitHub-Logos/GitHub_Logo.png | Bin .../GitHub-Logos/GitHub-Logos/GitHub_Logo.psd | Bin .../GitHub-Logos/GitHub_Logo_White.png | Bin .../GitHub-Logos/GitHub_Logo_White.psd | Bin .../GitHub-Logos/GitHub-Logos/README.txt | 0 .../GitHub-Logos/__MACOSX/._GitHub-Logos | Bin .../__MACOSX/GitHub-Logos/._GitHub_Logo.ai | Bin .../__MACOSX/GitHub-Logos/._GitHub_Logo.eps | Bin .../__MACOSX/GitHub-Logos/._GitHub_Logo.png | Bin .../__MACOSX/GitHub-Logos/._GitHub_Logo.psd | Bin .../GitHub-Logos/._GitHub_Logo_White.png | Bin .../GitHub-Logos/._GitHub_Logo_White.psd | Bin .../__MACOSX/GitHub-Logos/._README.txt | Bin .../lib/organizations/github/github-mark.zip | Bin .../github/github-mark/__MACOSX/._github-mark | Bin .../github-mark/._github-mark-white.png | Bin .../github-mark/._github-mark-white.svg | Bin .../__MACOSX/github-mark/._github-mark.png | Bin .../__MACOSX/github-mark/._github-mark.svg | Bin .../github-mark/github-mark-white.png | Bin .../github-mark/github-mark-white.svg | 0 .../github-mark/github-mark/github-mark.png | Bin .../github-mark/github-mark/github-mark.svg | 0 .../gitlab.com/gitlab-logo-700.svg | 0 .../src}/lib/organizations/hoc/92327702.png | Bin .../src}/lib/organizations/hoc/Favicon.png | Bin .../instagram/IG_brand_asset_pack_2022.zip | Bin .../Instagram_Glyph_Gradient copy.jpg | Bin .../Instagram_Glyph_Gradient copy.png | Bin .../Instagram_Glyph_Gradient.ai | 0 .../Instagram_Glyph_Gradient.jpg | Bin .../Instagram_Glyph_Gradient.png | Bin .../Instagram_Glyph_Gradient_RGB.svg | 0 .../02 White Glyph/Instagram_Glyph_White.ai | 0 .../02 White Glyph/Instagram_Glyph_White.png | Bin .../02 White Glyph/Instagram_Glyph_White.svg | 0 .../03 Black Glyph/Instagram_Glyph_Black.ai | 0 .../03 Black Glyph/Instagram_Glyph_Black.jpg | Bin .../03 Black Glyph/Instagram_Glyph_Black.png | Bin .../03 Black Glyph/Instagram_Glyph_Black.svg | 0 .../src}/lib/organizations/ipfs/ipfs.svg | 0 .../joinmastodon.org/logo-black.svg | 0 .../joinmastodon.org/logo-purple.png | Bin .../joinmastodon.org/logo-purple.svg | 0 .../lexfridman-podcast/download.jpeg | Bin .../organizations/linkedin/LinkedIn-Logos.zip | Bin .../linkedin/LinkedIn-Logos/LI-In-Bug.png | Bin .../linkedin/LinkedIn-Logos/LI-Logo.png | Bin .../organizations/linkedin/linkedin-logos.zip | Bin .../In-Blue-128-\316\223\303\244\303\263.png" | Bin .../1x/In-Blue-128-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/In-Blue-128.png | Bin .../In-Blue-14-\316\223\303\244\303\263.png" | Bin .../1x/In-Blue-14-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/In-Blue-14.png | Bin .../In-Blue-21-\316\223\303\244\303\263.png" | Bin .../1x/In-Blue-21-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/In-Blue-21.png | Bin .../In-Blue-26-\316\223\303\244\303\263.png" | Bin .../1x/In-Blue-26-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/In-Blue-26.png | Bin .../In-Blue-34-\316\223\303\244\303\263.png" | Bin .../1x/In-Blue-34-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/In-Blue-34.png | Bin .../In-Blue-40-\316\223\303\244\303\263.png" | Bin .../1x/In-Blue-40-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/In-Blue-40.png | Bin .../In-Blue-48-\316\223\303\244\303\263.png" | Bin .../1x/In-Blue-48-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/In-Blue-48.png | Bin .../In-Blue-72-\316\223\303\244\303\263.png" | Bin .../1x/In-Blue-72-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/In-Blue-72.png | Bin .../In-Blue-96-\316\223\303\244\303\263.png" | Bin .../1x/In-Blue-96-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/In-Blue-96.png | Bin ...-Blue-128-\316\223\303\244\303\263@2x.png" | Bin .../In-Blue-128-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/In-Blue-128@2x.png | Bin ...n-Blue-14-\316\223\303\244\303\263@2x.png" | Bin .../In-Blue-14-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/In-Blue-14@2x.png | Bin ...n-Blue-21-\316\223\303\244\303\263@2x.png" | Bin .../In-Blue-21-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/In-Blue-21@2x.png | Bin ...n-Blue-26-\316\223\303\244\303\263@2x.png" | Bin .../In-Blue-26-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/In-Blue-26@2x.png | Bin ...n-Blue-34-\316\223\303\244\303\263@2x.png" | Bin .../In-Blue-34-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/In-Blue-34@2x.png | Bin ...n-Blue-40-\316\223\303\244\303\263@2x.png" | Bin .../In-Blue-40-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/In-Blue-40@2x.png | Bin ...n-Blue-48-\316\223\303\244\303\263@2x.png" | Bin .../In-Blue-48-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/In-Blue-48@2x.png | Bin ...n-Blue-72-\316\223\303\244\303\263@2x.png" | Bin .../In-Blue-72-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/In-Blue-72@2x.png | Bin ...n-Blue-96-\316\223\303\244\303\263@2x.png" | Bin .../In-Blue-96-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/In-Blue-96@2x.png | Bin ...In-White-128-\316\223\303\244\303\263.png" | Bin .../1x/In-White-128-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/In-White-128.png | Bin .../In-White-14-\316\223\303\244\303\263.png" | Bin .../1x/In-White-14-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/In-White-14.png | Bin .../In-White-21-\316\223\303\244\303\263.png" | Bin .../1x/In-White-21-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/In-White-21.png | Bin .../In-White-26-\316\223\303\244\303\263.png" | Bin .../1x/In-White-26-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/In-White-26.png | Bin .../In-White-34-\316\223\303\244\303\263.png" | Bin .../1x/In-White-34-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/In-White-34.png | Bin .../In-White-40-\316\223\303\244\303\263.png" | Bin .../1x/In-White-40-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/In-White-40.png | Bin .../In-White-48-\316\223\303\244\303\263.png" | Bin .../1x/In-White-48-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/In-White-48.png | Bin .../In-White-72-\316\223\303\244\303\263.png" | Bin .../1x/In-White-72-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/In-White-72.png | Bin .../In-White-96-\316\223\303\244\303\263.png" | Bin .../1x/In-White-96-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/In-White-96.png | Bin ...White-128-\316\223\303\244\303\263@2x.png" | Bin .../In-White-128-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/In-White-128@2x.png | Bin ...-White-14-\316\223\303\244\303\263@2x.png" | Bin .../In-White-14-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/In-White-14@2x.png | Bin ...-White-21-\316\223\303\244\303\263@2x.png" | Bin .../In-White-21-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/In-White-21@2x.png | Bin ...-White-26-\316\223\303\244\303\263@2x.png" | Bin .../In-White-26-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/In-White-26@2x.png | Bin ...-White-34-\316\223\303\244\303\263@2x.png" | Bin .../In-White-34-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/In-White-34@2x.png | Bin ...-White-40-\316\223\303\244\303\263@2x.png" | Bin .../In-White-40-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/In-White-40@2x.png | Bin ...-White-48-\316\223\303\244\303\263@2x.png" | Bin .../In-White-48-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/In-White-48@2x.png | Bin ...-White-72-\316\223\303\244\303\263@2x.png" | Bin .../In-White-72-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/In-White-72@2x.png | Bin ...-White-96-\316\223\303\244\303\263@2x.png" | Bin .../In-White-96-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/In-White-96@2x.png | Bin ...-CMYK-Blue-L-\316\223\303\244\303\263.eps" | Bin .../In-CMYK-Blue-L-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/Blue/In-CMYK-Blue-L.eps | Bin ...-CMYK-Blue-M-\316\223\303\244\303\263.eps" | Bin .../In-CMYK-Blue-M-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/Blue/In-CMYK-Blue-M.eps | Bin ...-CMYK-Blue-S-\316\223\303\244\303\263.eps" | Bin .../In-CMYK-Blue-S-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/Blue/In-CMYK-Blue-S.eps | Bin ...CMYK-White-L-\316\223\303\244\303\263.eps" | Bin .../In-CMYK-White-L-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/White/In-CMYK-White-L.eps | Bin ...CMYK-White-M-\316\223\303\244\303\263.eps" | Bin .../In-CMYK-White-M-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/White/In-CMYK-White-M.eps | Bin ...CMYK-White-S-\316\223\303\244\303\263.eps" | Bin .../In-CMYK-White-S-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/White/In-CMYK-White-S.eps | Bin ...n-PMS2174U-L-\316\223\303\244\303\263.eps" | Bin .../In-PMS2174U-L-\342\224\254\302\253.eps" | Bin .../In/Print/PMS/In-PMS2174U-L.eps | Bin ...n-PMS2174U-M-\316\223\303\244\303\263.eps" | Bin .../In-PMS2174U-M-\342\224\254\302\253.eps" | Bin .../In/Print/PMS/In-PMS2174U-M.eps | Bin ...n-PMS2174U-S-\316\223\303\244\303\263.eps" | Bin .../In-PMS2174U-S-\342\224\254\302\253.eps" | Bin .../In/Print/PMS/In-PMS2174U-S.eps | Bin ...\316\223\303\244\303\263@2x.png_Error.txt" | 0 ...edIn-Blue-128-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/LinkedIn-Blue-128@2x.png | Bin ...n-Blue-14-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-14-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/LinkedIn-Blue-14@2x.png | Bin ...n-Blue-21-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-21-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/LinkedIn-Blue-21@2x.png | Bin ...kedIn-Blue-26-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/LinkedIn-Blue-26@2x.png | Bin ...n-Blue-34-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-34-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/LinkedIn-Blue-34@2x.png | Bin ...n-Blue-40-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-40-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/LinkedIn-Blue-40@2x.png | Bin ...n-Blue-48-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-48-\342\224\254\302\253@2x.png" | Bin ...n-Blue-72-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-72-\342\224\254\302\253@2x.png" | Bin ...n-Blue-96-\316\223\303\244\303\263@2x.png" | Bin .../Digital/Blue/2x/LinkedIn-Blue-96@2x.png | Bin ...-CMYK-Blue-L-\316\223\303\244\303\263.eps" | Bin ...edIn-CMYK-Blue-L-\342\224\254\302\253.eps" | Bin .../Print/CMYK/Blue/LinkedIn-CMYK-Blue-L.eps | Bin ...-CMYK-Blue-M-\316\223\303\244\303\263.eps" | Bin ...edIn-CMYK-Blue-M-\342\224\254\302\253.eps" | Bin .../Print/CMYK/Blue/LinkedIn-CMYK-Blue-M.eps | Bin ...-CMYK-Blue-S-\316\223\303\244\303\263.eps" | Bin ...edIn-CMYK-Blue-S-\342\224\254\302\253.eps" | Bin .../Print/CMYK/Blue/LinkedIn-CMYK-Blue-S.eps | Bin ...CMYK-White-L-\316\223\303\244\303\263.eps" | Bin ...dIn-CMYK-White-L-\342\224\254\302\253.eps" | Bin .../CMYK/White/LinkedIn-CMYK-White-L.eps | Bin ...CMYK-White-M-\316\223\303\244\303\263.eps" | Bin ...dIn-CMYK-White-M-\342\224\254\302\253.eps" | Bin .../CMYK/White/LinkedIn-CMYK-White-M.eps | Bin ...CMYK-White-S-\316\223\303\244\303\263.eps" | Bin ...dIn-CMYK-White-S-\342\224\254\302\253.eps" | Bin .../CMYK/White/LinkedIn-CMYK-White-S.eps | Bin ...n-PMS2174U-L-\316\223\303\244\303\263.eps" | Bin ...kedIn-PMS2174U-L-\342\224\254\302\253.eps" | Bin .../Logo/Print/PMS/LinkedIn-PMS2174U-L.eps | Bin ...n-PMS2174U-M-\316\223\303\244\303\263.eps" | Bin .../Logo/Print/PMS/LinkedIn-PMS2174U-M.eps | Bin ...n-PMS2174U-S-\316\223\303\244\303\263.eps" | Bin ...kedIn-PMS2174U-S-\342\224\254\302\253.eps" | Bin .../Logo/Print/PMS/LinkedIn-PMS2174U-S.eps | Bin .../linkedin-logos/__MACOSX/._LinkedIn-Logos | Bin .../__MACOSX/LinkedIn-Logos/._In | Bin .../__MACOSX/LinkedIn-Logos/._Logo | Bin .../__MACOSX/LinkedIn-Logos/In/._Digital | Bin .../__MACOSX/LinkedIn-Logos/In/._Print | Bin .../__MACOSX/LinkedIn-Logos/In/Digital/._Blue | Bin .../LinkedIn-Logos/In/Digital/._White | Bin .../LinkedIn-Logos/In/Digital/Blue/._1x | Bin .../LinkedIn-Logos/In/Digital/Blue/._2x | Bin ..._In-Blue-128-\316\223\303\244\303\263.png" | Bin .../._In-Blue-128-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/._In-Blue-128.png | Bin ...._In-Blue-14-\316\223\303\244\303\263.png" | Bin .../1x/._In-Blue-14-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/._In-Blue-14.png | Bin ...._In-Blue-21-\316\223\303\244\303\263.png" | Bin .../1x/._In-Blue-21-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/._In-Blue-21.png | Bin ...._In-Blue-26-\316\223\303\244\303\263.png" | Bin .../1x/._In-Blue-26-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/._In-Blue-26.png | Bin ...._In-Blue-34-\316\223\303\244\303\263.png" | Bin .../1x/._In-Blue-34-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/._In-Blue-34.png | Bin ...._In-Blue-40-\316\223\303\244\303\263.png" | Bin .../1x/._In-Blue-40-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/._In-Blue-40.png | Bin ...._In-Blue-48-\316\223\303\244\303\263.png" | Bin .../1x/._In-Blue-48-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/._In-Blue-48.png | Bin ...._In-Blue-72-\316\223\303\244\303\263.png" | Bin .../1x/._In-Blue-72-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/._In-Blue-72.png | Bin ...._In-Blue-96-\316\223\303\244\303\263.png" | Bin .../1x/._In-Blue-96-\342\224\254\302\253.png" | Bin .../In/Digital/Blue/1x/._In-Blue-96.png | Bin ...-Blue-128-\316\223\303\244\303\263@2x.png" | Bin ...._In-Blue-128-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/._In-Blue-128@2x.png | Bin ...n-Blue-14-\316\223\303\244\303\263@2x.png" | Bin .../._In-Blue-14-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/._In-Blue-14@2x.png | Bin ...n-Blue-21-\316\223\303\244\303\263@2x.png" | Bin .../._In-Blue-21-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/._In-Blue-21@2x.png | Bin ...n-Blue-26-\316\223\303\244\303\263@2x.png" | Bin .../._In-Blue-26-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/._In-Blue-26@2x.png | Bin ...n-Blue-34-\316\223\303\244\303\263@2x.png" | Bin .../._In-Blue-34-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/._In-Blue-34@2x.png | Bin ...n-Blue-40-\316\223\303\244\303\263@2x.png" | Bin .../._In-Blue-40-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/._In-Blue-40@2x.png | Bin ...n-Blue-48-\316\223\303\244\303\263@2x.png" | Bin .../._In-Blue-48-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/._In-Blue-48@2x.png | Bin ...n-Blue-72-\316\223\303\244\303\263@2x.png" | Bin .../._In-Blue-72-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/._In-Blue-72@2x.png | Bin ...n-Blue-96-\316\223\303\244\303\263@2x.png" | Bin .../._In-Blue-96-\342\224\254\302\253@2x.png" | Bin .../In/Digital/Blue/2x/._In-Blue-96@2x.png | Bin .../LinkedIn-Logos/In/Digital/White/._1x | Bin .../LinkedIn-Logos/In/Digital/White/._2x | Bin ...In-White-128-\316\223\303\244\303\263.png" | Bin .../._In-White-128-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/._In-White-128.png | Bin ..._In-White-14-\316\223\303\244\303\263.png" | Bin .../._In-White-14-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/._In-White-14.png | Bin ..._In-White-21-\316\223\303\244\303\263.png" | Bin .../._In-White-21-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/._In-White-21.png | Bin ..._In-White-26-\316\223\303\244\303\263.png" | Bin .../._In-White-26-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/._In-White-26.png | Bin ..._In-White-34-\316\223\303\244\303\263.png" | Bin .../._In-White-34-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/._In-White-34.png | Bin ..._In-White-40-\316\223\303\244\303\263.png" | Bin .../._In-White-40-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/._In-White-40.png | Bin ..._In-White-48-\316\223\303\244\303\263.png" | Bin .../._In-White-48-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/._In-White-48.png | Bin ..._In-White-72-\316\223\303\244\303\263.png" | Bin .../._In-White-72-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/._In-White-72.png | Bin ..._In-White-96-\316\223\303\244\303\263.png" | Bin .../._In-White-96-\342\224\254\302\253.png" | Bin .../In/Digital/White/1x/._In-White-96.png | Bin ...White-128-\316\223\303\244\303\263@2x.png" | Bin ..._In-White-128-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/._In-White-128@2x.png | Bin ...-White-14-\316\223\303\244\303\263@2x.png" | Bin ...._In-White-14-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/._In-White-14@2x.png | Bin ...-White-21-\316\223\303\244\303\263@2x.png" | Bin ...._In-White-21-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/._In-White-21@2x.png | Bin ...-White-26-\316\223\303\244\303\263@2x.png" | Bin ...._In-White-26-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/._In-White-26@2x.png | Bin ...-White-34-\316\223\303\244\303\263@2x.png" | Bin ...._In-White-34-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/._In-White-34@2x.png | Bin ...-White-40-\316\223\303\244\303\263@2x.png" | Bin ...._In-White-40-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/._In-White-40@2x.png | Bin ...-White-48-\316\223\303\244\303\263@2x.png" | Bin ...._In-White-48-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/._In-White-48@2x.png | Bin ...-White-72-\316\223\303\244\303\263@2x.png" | Bin ...._In-White-72-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/._In-White-72@2x.png | Bin ...-White-96-\316\223\303\244\303\263@2x.png" | Bin ...._In-White-96-\342\224\254\302\253@2x.png" | Bin .../In/Digital/White/2x/._In-White-96@2x.png | Bin .../__MACOSX/LinkedIn-Logos/In/Print/._CMYK | Bin .../__MACOSX/LinkedIn-Logos/In/Print/._PMS | Bin .../LinkedIn-Logos/In/Print/CMYK/._Blue | Bin .../LinkedIn-Logos/In/Print/CMYK/._White | Bin ...-CMYK-Blue-L-\316\223\303\244\303\263.eps" | Bin ...._In-CMYK-Blue-L-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/Blue/._In-CMYK-Blue-L.eps | Bin ...-CMYK-Blue-M-\316\223\303\244\303\263.eps" | Bin ...._In-CMYK-Blue-M-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/Blue/._In-CMYK-Blue-M.eps | Bin ...-CMYK-Blue-S-\316\223\303\244\303\263.eps" | Bin ...._In-CMYK-Blue-S-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/Blue/._In-CMYK-Blue-S.eps | Bin ...CMYK-White-L-\316\223\303\244\303\263.eps" | Bin ..._In-CMYK-White-L-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/White/._In-CMYK-White-L.eps | Bin ...CMYK-White-M-\316\223\303\244\303\263.eps" | Bin ..._In-CMYK-White-M-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/White/._In-CMYK-White-M.eps | Bin ...CMYK-White-S-\316\223\303\244\303\263.eps" | Bin ..._In-CMYK-White-S-\342\224\254\302\253.eps" | Bin .../In/Print/CMYK/White/._In-CMYK-White-S.eps | Bin ...n-PMS2174U-L-\316\223\303\244\303\263.eps" | Bin .../._In-PMS2174U-L-\342\224\254\302\253.eps" | Bin .../In/Print/PMS/._In-PMS2174U-L.eps | Bin ...n-PMS2174U-M-\316\223\303\244\303\263.eps" | Bin .../._In-PMS2174U-M-\342\224\254\302\253.eps" | Bin .../In/Print/PMS/._In-PMS2174U-M.eps | Bin ...n-PMS2174U-S-\316\223\303\244\303\263.eps" | Bin .../._In-PMS2174U-S-\342\224\254\302\253.eps" | Bin .../In/Print/PMS/._In-PMS2174U-S.eps | Bin .../__MACOSX/LinkedIn-Logos/Logo/._Digital | Bin .../__MACOSX/LinkedIn-Logos/Logo/._Print | Bin .../LinkedIn-Logos/Logo/Digital/._Blue | Bin .../LinkedIn-Logos/Logo/Digital/Blue/._2x | Bin ...\316\223\303\244\303\263@2x.png_Error.txt" | Bin ...edIn-Blue-128-\342\224\254\302\253@2x.png" | Bin .../Blue/2x/._LinkedIn-Blue-128@2x.png | Bin ...n-Blue-14-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-14-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/._LinkedIn-Blue-14@2x.png | Bin ...n-Blue-21-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-21-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/._LinkedIn-Blue-21@2x.png | Bin ...kedIn-Blue-26-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/._LinkedIn-Blue-26@2x.png | Bin ...n-Blue-34-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-34-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/._LinkedIn-Blue-34@2x.png | Bin ...n-Blue-40-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-40-\342\224\254\302\253@2x.png" | Bin .../Digital/Blue/2x/._LinkedIn-Blue-40@2x.png | Bin ...n-Blue-48-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-48-\342\224\254\302\253@2x.png" | Bin ...n-Blue-72-\316\223\303\244\303\263@2x.png" | Bin ...kedIn-Blue-72-\342\224\254\302\253@2x.png" | Bin ...n-Blue-96-\316\223\303\244\303\263@2x.png" | Bin .../Digital/Blue/2x/._LinkedIn-Blue-96@2x.png | Bin .../__MACOSX/LinkedIn-Logos/Logo/Print/._CMYK | Bin .../__MACOSX/LinkedIn-Logos/Logo/Print/._PMS | Bin .../LinkedIn-Logos/Logo/Print/CMYK/._Blue | Bin .../LinkedIn-Logos/Logo/Print/CMYK/._White | Bin ...-CMYK-Blue-L-\316\223\303\244\303\263.eps" | Bin ...edIn-CMYK-Blue-L-\342\224\254\302\253.eps" | Bin .../CMYK/Blue/._LinkedIn-CMYK-Blue-L.eps | Bin ...-CMYK-Blue-M-\316\223\303\244\303\263.eps" | Bin ...edIn-CMYK-Blue-M-\342\224\254\302\253.eps" | Bin .../CMYK/Blue/._LinkedIn-CMYK-Blue-M.eps | Bin ...-CMYK-Blue-S-\316\223\303\244\303\263.eps" | Bin ...edIn-CMYK-Blue-S-\342\224\254\302\253.eps" | Bin .../CMYK/Blue/._LinkedIn-CMYK-Blue-S.eps | Bin ...CMYK-White-L-\316\223\303\244\303\263.eps" | Bin ...dIn-CMYK-White-L-\342\224\254\302\253.eps" | Bin .../CMYK/White/._LinkedIn-CMYK-White-L.eps | Bin ...CMYK-White-M-\316\223\303\244\303\263.eps" | Bin ...dIn-CMYK-White-M-\342\224\254\302\253.eps" | Bin .../CMYK/White/._LinkedIn-CMYK-White-M.eps | Bin ...CMYK-White-S-\316\223\303\244\303\263.eps" | Bin ...dIn-CMYK-White-S-\342\224\254\302\253.eps" | Bin .../CMYK/White/._LinkedIn-CMYK-White-S.eps | Bin ...n-PMS2174U-L-\316\223\303\244\303\263.eps" | Bin ...kedIn-PMS2174U-L-\342\224\254\302\253.eps" | Bin .../Logo/Print/PMS/._LinkedIn-PMS2174U-L.eps | Bin ...n-PMS2174U-M-\316\223\303\244\303\263.eps" | Bin .../Logo/Print/PMS/._LinkedIn-PMS2174U-M.eps | Bin ...n-PMS2174U-S-\316\223\303\244\303\263.eps" | Bin ...kedIn-PMS2174U-S-\342\224\254\302\253.eps" | Bin .../Logo/Print/PMS/._LinkedIn-PMS2174U-S.eps | Bin .../linkedin/linkedin-svgrepo-com.svg | 0 .../meta/Facebook-Brand-Asset-Pack.zip | Bin .../Primary Logo/Facebook_Logo_Primary.ai | 0 .../Primary Logo/Facebook_Logo_Primary.png | Bin .../Secondary Logo/Facebook_Logo_Secondary.ai | 0 .../Facebook_Logo_Secondary.png | Bin .../meta/Meta_Company-Lockup.zip | Bin .../RGB/Meta_lockup_positive primary_RGB.ai | 0 .../RGB/Meta_lockup_positive primary_RGB.jpg | Bin .../RGB/Meta_lockup_positive primary_RGB.png | Bin .../RGB/Meta_lockup_positive primary_RGB.svg | 0 .../Meta_lockup_negative primary_white_RGB.ai | 0 ...Meta_lockup_negative primary_white_RGB.png | Bin ...Meta_lockup_negative primary_white_RGB.svg | 0 .../RGB/Meta_lockup_mono_black_RGB.ai | 0 .../RGB/Meta_lockup_mono_black_RGB.png | Bin .../RGB/Meta_lockup_mono_black_RGB.svg | 0 .../RGB/Meta_lockup_mono_white_RGB.ai | 0 .../RGB/Meta_lockup_mono_white_RGB.png | Bin .../RGB/Meta_lockup_mono_white_RGB.svg | 0 .../meta/WhatsApp-Brand-Resource-Center.zip | Bin .../01_AI/Black/Digital_Glyph_Black.ai | 0 .../Dark Green/Digital_Glyph_Dark_Green.ai | 0 .../01_AI/Green/Digital_Glyph_Green.ai | 0 .../01_AI/White/Digital_Glyph_White.ai | 0 .../02_SVG/Black/Digital_Glyph_Black.svg | 0 .../Dark Green/Digital_Glyph_Dark_Green.svg | 0 .../02_SVG/Green/Digital_Glyph_Green.svg | 0 .../02_SVG/White/Digital_Glyph_White.svg | 0 .../03_PNG/Black/Digital_Glyph_Black.png | Bin .../Dark Green/Digital_Glyph_Dark_Green.png | Bin .../03_PNG/Green/Digital_Glyph_Green.png | Bin .../03_PNG/White/Digital_Glyph_White.png | Bin .../02_Print/01_AI/Black/Print_Glyph_Black.ai | 0 .../Dark Green/Print_Glyph_Dark_Green.ai | 0 .../02_Print/01_AI/Green/Print_Glyph_Green.ai | 0 .../02_Print/01_AI/White/Print_Glyph_White.ai | 0 .../03_PNG/Black/Print_Glyph_Black.png | Bin .../Dark Green/Print_Glyph_Dark_Green.png | Bin .../03_PNG/Green/Print_Glyph_Green.png | Bin .../03_PNG/White/Print_Glyph_White.png | Bin .../01_AI/Black/Digital_Inline_Black.ai | 0 .../Dark Green/Digital_Inline_Dark_Green.ai | 0 .../01_AI/Green/Digital_Inline_Green.ai | 0 .../01_AI/White/Digital_Inline_White.ai | 0 .../02_SVG/Black/Digital_Inline_Black.svg | 0 .../Dark Green/Digital_Inline_Dark_Green.svg | 0 .../02_SVG/Green/Digital_Inline_Green.svg | 0 .../02_SVG/White/Digital_Inline_White.svg | 0 .../03_PNG/Black/Digital_Inline_Black.png | Bin .../Dark Green/Digital_Inline_Dark_Green.png | Bin .../03_PNG/Green/Digital_Inline_Green.png | Bin .../03_PNG/White/Digital_Inline_White.png | Bin .../01_AI/Black/Print_Inline_Black.ai | 0 .../Dark Green/Print_Inline_Dark_Green.ai | 0 .../01_AI/Green/Print_Inline_Green.ai | 0 .../01_AI/White/Print_Inline_White.ai | 0 .../03_PNG/Black/Print_Inline_Black.png | Bin .../Dark Green/Print_Inline_Dark_Green.png | Bin .../03_PNG/Green/Print_Inline_Green.png | Bin .../03_PNG/White/Print_Inline_White.png | Bin .../01_AI/Black/Digital_Stacked_Black.ai | 0 .../Dark Green/Digital_Stacked_Dark_Green.ai | 0 .../01_AI/Green/Digital_Stacked_Green.ai | 0 .../01_AI/White/Digital_Stacked_White.ai | 0 .../02_SVG/Black/Digital_Stacked_Black.svg | 0 .../Dark Green/Digital_Stacked_Dark_Green.svg | 0 .../02_SVG/Green/Digital_Stacked_Green.svg | 0 .../02_SVG/White/Digital_Stacked_White.svg | 0 .../03_PNG/Black/Digital_Stacked_Black.png | Bin .../Dark Green/Digital_Stacked_Dark_Green.png | Bin .../03_PNG/Green/Digital_Stacked_Green.png | Bin .../03_PNG/White/Digital_Stacked_White.png | Bin .../01_AI/Black/Print_Stacked_Black.ai | 0 .../Dark Green/Print_Stacked_Dark_Green.ai | 0 .../01_AI/Green/Print_Stacked_Green.ai | 0 .../01_AI/White/Print_Stacked_White.ai | 0 .../03_PNG/Black/Print_Stacked_Black.png | Bin .../Dark Green/Print_Stacked_Dark_Green.png | Bin .../03_PNG/Green/Print_Stacked_Green.png | Bin .../03_PNG/White/Print_Stacked_White.png | Bin .../organizations/mlst/channels4_profile.jpg | Bin .../ngi/Logo-NGI_Icon-circle-NGI-rgb.png | Bin .../lib/organizations/nixos/nixos-icon.svg | 0 .../legacy/orbitmines.icon.legacy.16x16.png | Bin .../legacy/orbitmines.icon.legacy.64x64.png | Bin .../legacy/orbitmines.icon.legacy.734x720.png | Bin .../icon/orbitmines.icon.550x550.2.png | Bin .../icon/orbitmines.icon.550x550.png | Bin .../orbitmines/icon/orbitmines.icon.64x64.png | Bin .../icon/orbitmines.icon.650x650.min.png | Bin .../icon/orbitmines.icon.650x650.png | Bin .../orbitmines.logo.legacy.2000x419.png | Bin .../orbitmines.logo.legacy.3436x720.png | Bin .../orbitmines.logo.legacy.3800x634.png | Bin .../logo/orbitmines.logo.2048x1152.png | Bin .../logo/orbitmines.logo.3000x1000.png | Bin .../orbitmines.minecraft.diamond.16x15.png | Bin .../orbitmines.minecraft.diamond.848x782.png | Bin .../orbitmines.minecraft.emerald.16x15.png | Bin .../orbitmines.minecraft.emerald.848x782.png | Bin .../orbitmines.minecraft.gold.16x15.png | Bin .../orbitmines.minecraft.gold.848x782.png | Bin .../orbitmines.minecraft.iron.16x15.png | Bin .../orbitmines.minecraft.iron.848x782.png | Bin ...necraft.server.icon.creative.1000x1000.png | Bin ...es.minecraft.server.icon.fog.1000x1000.png | Bin ....minecraft.server.icon.fog.2.1000x1000.png | Bin ...minecraft.server.icon.kitpvp.1000x1000.png | Bin ...ecraft.server.icon.minigames.1000x1000.png | Bin ...minecraft.server.icon.prison.1000x1000.png | Bin ...necraft.server.icon.skyblock.1000x1000.png | Bin ...necraft.server.icon.survival.1000x1000.png | Bin ...inecraft.server.logo.creative.1000x300.png | Bin ...nes.minecraft.server.logo.fog.1000x300.png | Bin ....minecraft.server.logo.kitpvp.1000x300.png | Bin ...necraft.server.logo.minigames.1000x300.png | Bin ....minecraft.server.logo.prison.1000x300.png | Bin ...inecraft.server.logo.skyblock.1000x300.png | Bin ...inecraft.server.logo.survival.1000x300.png | Bin .../src}/lib/organizations/orcid/5008697.zip | Bin .../orcid/5008697/ORCID-iD_icon-128x128.gif | Bin .../orcid/5008697/ORCID-iD_icon-128x128.png | Bin .../orcid/5008697/ORCID-iD_icon-16x16.gif | Bin .../orcid/5008697/ORCID-iD_icon-16x16.png | Bin .../orcid/5008697/ORCID-iD_icon-24x24.gif | Bin .../orcid/5008697/ORCID-iD_icon-24x24.png | Bin .../orcid/5008697/ORCID-iD_icon-32x32.gif | Bin .../orcid/5008697/ORCID-iD_icon-32x32.png | Bin .../orcid/5008697/ORCID-iD_icon-64x64.gif | Bin .../orcid/5008697/ORCID-iD_icon-64x64.png | Bin .../5008697/ORCID-iD_icon-bw-128x128.gif | Bin .../5008697/ORCID-iD_icon-bw-128x128.png | Bin .../orcid/5008697/ORCID-iD_icon-bw-16x16.gif | Bin .../orcid/5008697/ORCID-iD_icon-bw-16x16.png | Bin .../orcid/5008697/ORCID-iD_icon-bw-24x24.gif | Bin .../orcid/5008697/ORCID-iD_icon-bw-24x24.png | Bin .../orcid/5008697/ORCID-iD_icon-bw-32x32.gif | Bin .../orcid/5008697/ORCID-iD_icon-bw-64x64.gif | Bin .../orcid/5008697/ORCID-iD_icon-bw-64x64.png | Bin .../orcid/5008697/ORCID-iD_icon-bw-vector.svg | 0 .../orcid/5008697/ORCID-iD_icon-vector.svg | 0 .../ORCID-iD_icon_reversed_128x128.png | Bin .../5008697/ORCID-iD_icon_reversed_24x24.png | Bin .../5008697/ORCID-iD_icon_reversed_32x32.png | Bin .../5008697/ORCID-iD_icon_reversed_vector.svg | 0 .../organizations/papers-we-love/6187757.png | Bin .../preposterous-universe/download.jpeg | Bin .../santa-fe-institute/0_OgRM7UU-SsqK46La.png | Bin .../src}/lib/organizations/semf/semf_icon.jpg | Bin ...e_loop_logo_final_color_no_year_square.jpg | Bin ..._loop_logo_final_color_no_year_square2.png | Bin ..._loop_logo_final_color_no_year_square2.xcf | Bin orbitmines.com/src/lib/organizations/temp.ts | 69 ++++++++++++++++++ .../lib/organizations/tinycorp/132956020.jpeg | Bin .../topos.institute/topos_favicon.ico | Bin .../twitch/twitch-brand-assets.zip | Bin .../Color Palette/TwitchColorPalette.ai | 0 .../Color Palette/TwitchColorPalette.ase | Bin .../Twitch_Guidelines_Speedrun_v2.pdf | Bin .../glitch/Black Ops/TwitchGlitchBlackOps.eps | Bin .../glitch/Black Ops/TwitchGlitchBlackOps.png | Bin .../glitch/Black Ops/TwitchGlitchBlackOps.svg | 0 .../glitch/Purple/TwitchGlitchPurple.eps | Bin .../glitch/Purple/TwitchGlitchPurple.png | Bin .../glitch/Purple/TwitchGlitchPurple.svg | 0 .../Logos/glitch/White/TwitchGlitchWhite.eps | Bin .../Logos/glitch/White/TwitchGlitchWhite.png | Bin .../Logos/glitch/White/TwitchGlitchWhite.svg | 0 .../TwitchExtrudedWordmarkBlackOps.eps | Bin .../TwitchExtrudedWordmarkBlackOps.png | Bin .../TwitchExtrudedWordmarkBlackOps.svg | 0 .../TwitchExtrudedWordmarkPurple.eps | Bin .../TwitchExtrudedWordmarkPurple.png | Bin .../TwitchExtrudedWordmarkPurple.svg | 0 .../Black Ops/Twitch-Wordmark-BlackOps.eps | Bin .../Twitch_UnextrudedWordmarkBlackOps.png | Bin .../Twitch_UnextrudedWordmarkBlackOps.svg | 0 .../Twitch_UnextrudedWordmarkPurple-01.eps | Bin .../Twitch_UnextrudedWordmarkPurple.png | Bin .../Twitch_UnextrudedWordmarkPurple.svg | 0 .../Wordmark/White/Twitch-Wordmark-White.eps | Bin .../Wordmark/White/Twitch-Wordmark-White.png | Bin .../Wordmark/White/Twitch-Wordmark-White.svg | 0 .../__MACOSX/._Brand Assets | Bin .../__MACOSX/Brand Assets/._Color Palette | Bin .../._Guidelines (Speedrun Edition) | Bin .../__MACOSX/Brand Assets/._Logos | Bin .../Color Palette/._TwitchColorPalette.ai | Bin .../Color Palette/._TwitchColorPalette.ase | Bin .../._Twitch_Guidelines_Speedrun_v2.pdf | Bin .../__MACOSX/Brand Assets/Logos/._glitch | Bin .../__MACOSX/Brand Assets/Logos/._wordmark | Bin .../Brand Assets/Logos/glitch/._Black Ops | Bin .../Brand Assets/Logos/glitch/._Purple | Bin .../Brand Assets/Logos/glitch/._White | Bin .../Black Ops/._TwitchGlitchBlackOps.eps | Bin .../Black Ops/._TwitchGlitchBlackOps.png | Bin .../Black Ops/._TwitchGlitchBlackOps.svg | Bin .../glitch/Purple/._TwitchGlitchPurple.eps | Bin .../glitch/Purple/._TwitchGlitchPurple.png | Bin .../glitch/Purple/._TwitchGlitchPurple.svg | Bin .../glitch/White/._TwitchGlitchWhite.eps | Bin .../glitch/White/._TwitchGlitchWhite.png | Bin .../glitch/White/._TwitchGlitchWhite.svg | Bin .../._Extruded Wordmark (Primary Logo) | Bin .../Brand Assets/Logos/wordmark/._Wordmark | Bin .../._Black Ops | Bin .../._Twitch Purple | Bin .../._TwitchExtrudedWordmarkBlackOps.eps | Bin .../._TwitchExtrudedWordmarkBlackOps.png | Bin .../._TwitchExtrudedWordmarkBlackOps.svg | Bin .../._TwitchExtrudedWordmarkPurple.eps | Bin .../._TwitchExtrudedWordmarkPurple.png | Bin .../._TwitchExtrudedWordmarkPurple.svg | Bin .../Logos/wordmark/Wordmark/._Black Ops | Bin .../Logos/wordmark/Wordmark/._Twitch Purple | Bin .../Logos/wordmark/Wordmark/._White | Bin .../Black Ops/._Twitch-Wordmark-BlackOps.eps | Bin .../._Twitch_UnextrudedWordmarkBlackOps.png | Bin .../._Twitch_UnextrudedWordmarkBlackOps.svg | Bin .../._Twitch_UnextrudedWordmarkPurple-01.eps | Bin .../._Twitch_UnextrudedWordmarkPurple.png | Bin .../._Twitch_UnextrudedWordmarkPurple.svg | Bin .../White/._Twitch-Wordmark-White.eps | Bin .../White/._Twitch-Wordmark-White.png | Bin .../White/._Twitch-Wordmark-White.svg | Bin .../twitch/twitch-white-icon.svg | 0 .../twitter/twitter-logo-01282021.zip | Bin .../EPS/2021 Twitter logo - black.eps | Bin .../EPS/2021 Twitter logo - blue.eps | Bin .../EPS/2021 Twitter logo - white.eps | Bin .../PNG/2021 Twitter logo - black.png | Bin .../PNG/2021 Twitter logo - blue.png | Bin .../PNG/2021 Twitter logo - white.png | Bin .../PSD/2021 Twitter logo - black.psd | Bin .../PSD/2021 Twitter logo - blue.psd | Bin .../PSD/2021 Twitter logo - white.psd | Bin .../Twitter logo/SVG/Logo black.svg | 0 .../Twitter logo/SVG/Logo blue.svg | 0 .../Twitter logo/SVG/Logo white.svg | 0 .../Twitter social icons - circle - blue.ai | 0 .../Twitter social icons - circle - blue.eps | Bin .../Twitter social icons - circle - blue.png | Bin .../Twitter social icons - circle - blue.psd | Bin .../Twitter social icons - circle - blue.svg | 0 .../Twitter social icons - circle - white.ai | 0 .../Twitter social icons - circle - white.eps | Bin .../Twitter social icons - circle - white.png | Bin .../Twitter social icons - circle - white.psd | Bin .../Twitter social icons - circle - white.svg | 0 ...er social icons - rounded square - blue.ai | 0 ...r social icons - rounded square - blue.eps | Bin ...r social icons - rounded square - blue.png | Bin ...r social icons - rounded square - blue.psd | Bin ...r social icons - rounded square - blue.svg | 0 ...r social icons - rounded square - white.ai | 0 ... social icons - rounded square - white.eps | Bin ... social icons - rounded square - white.png | Bin ... social icons - rounded square - white.psd | Bin ... social icons - rounded square - white.svg | 0 .../Twitter social icons - square - blue.ai | 0 .../Twitter social icons - square - blue.eps | Bin .../Twitter social icons - square - blue.png | Bin .../Twitter social icons - square - blue.psd | Bin .../Twitter social icons - square - blue.svg | 0 .../Twitter social icons - square - white.ai | 0 .../Twitter social icons - square - white.eps | Bin .../Twitter social icons - square - white.png | Bin .../Twitter social icons - square - white.psd | Bin .../Twitter social icons - square - white.svg | 0 .../__MACOSX/._Twitter logo | Bin .../__MACOSX/._Twitter social icons | Bin .../__MACOSX/Twitter logo/._EPS | Bin .../__MACOSX/Twitter logo/._PNG | Bin .../__MACOSX/Twitter logo/._PSD | Bin .../__MACOSX/Twitter logo/._SVG | Bin .../EPS/._2021 Twitter logo - black.eps | Bin .../EPS/._2021 Twitter logo - blue.eps | Bin .../EPS/._2021 Twitter logo - white.eps | Bin .../PNG/._2021 Twitter logo - black.png | Bin .../PNG/._2021 Twitter logo - blue.png | Bin .../PNG/._2021 Twitter logo - white.png | Bin .../PSD/._2021 Twitter logo - black.psd | Bin .../PSD/._2021 Twitter logo - blue.psd | Bin .../PSD/._2021 Twitter logo - white.psd | Bin .../Twitter logo/SVG/._Logo black.svg | Bin .../__MACOSX/Twitter logo/SVG/._Logo blue.svg | Bin .../Twitter logo/SVG/._Logo white.svg | Bin .../._Twitter social icons - circle | Bin .../._Twitter social icons - rounded square | Bin .../._Twitter social icons - square | Bin .../._Twitter social icons - circle - blue.ai | Bin ...._Twitter social icons - circle - blue.eps | Bin ...._Twitter social icons - circle - blue.png | Bin ...._Twitter social icons - circle - blue.psd | Bin ...._Twitter social icons - circle - blue.svg | Bin ...._Twitter social icons - circle - white.ai | Bin ..._Twitter social icons - circle - white.eps | Bin ..._Twitter social icons - circle - white.png | Bin ..._Twitter social icons - circle - white.psd | Bin ..._Twitter social icons - circle - white.svg | Bin ...er social icons - rounded square - blue.ai | Bin ...r social icons - rounded square - blue.eps | Bin ...r social icons - rounded square - blue.png | Bin ...r social icons - rounded square - blue.psd | Bin ...r social icons - rounded square - blue.svg | Bin ...r social icons - rounded square - white.ai | Bin ... social icons - rounded square - white.eps | Bin ... social icons - rounded square - white.png | Bin ... social icons - rounded square - white.psd | Bin ... social icons - rounded square - white.svg | Bin .../._Twitter social icons - square - blue.ai | Bin ...._Twitter social icons - square - blue.eps | Bin ...._Twitter social icons - square - blue.png | Bin ...._Twitter social icons - square - blue.psd | Bin ...._Twitter social icons - square - blue.svg | Bin ...._Twitter social icons - square - white.ai | Bin ..._Twitter social icons - square - white.eps | Bin ..._Twitter social icons - square - white.png | Bin ..._Twitter social icons - square - white.psd | Bin ..._Twitter social icons - square - white.svg | Bin .../twitter-partnership-lockups-01272021.zip | Bin ...rtnership lockups - brand loves Twitter.ai | 0 ...tnership lockups - brand loves Twitter.png | Bin ...artner - In partnership with - centered.ai | 0 ...rtner - In partnership with - centered.png | Bin ...ne partner - In partnership with - left.ai | 0 ...e partner - In partnership with - left.png | Bin ...p lockups - one partner - Twitter after.ai | 0 ... lockups - one partner - Twitter after.png | Bin ...p lockups - one partner - Twitter first.ai | 0 ... lockups - one partner - Twitter first.png | Bin ...rtners - In partnership with - centered.ai | 0 ...tners - In partnership with - centered.png | Bin ...e partners - In partnership with - left.ai | 0 ... partners - In partnership with - left.png | Bin ... lockups - two partners - Twitter after.ai | 0 ...lockups - two partners - Twitter after.png | Bin ... lockups - two partners - Twitter first.ai | 0 ...lockups - two partners - Twitter first.png | Bin ...ershipPairingLockup_Templates_Helvetica.ai | 0 .../__MACOSX/._Twitter partnership lockups | Bin ...rtnership lockups - brand loves Twitter.ai | Bin ...tnership lockups - brand loves Twitter.png | Bin ...artner - In partnership with - centered.ai | Bin ...rtner - In partnership with - centered.png | Bin ...ne partner - In partnership with - left.ai | Bin ...e partner - In partnership with - left.png | Bin ...p lockups - one partner - Twitter after.ai | Bin ... lockups - one partner - Twitter after.png | Bin ...p lockups - one partner - Twitter first.ai | Bin ... lockups - one partner - Twitter first.png | Bin ...rtners - In partnership with - centered.ai | Bin ...tners - In partnership with - centered.png | Bin ...e partners - In partnership with - left.ai | Bin ... partners - In partnership with - left.png | Bin ... lockups - two partners - Twitter after.ai | Bin ...lockups - two partners - Twitter after.png | Bin ... lockups - two partners - Twitter first.ai | Bin ...lockups - two partners - Twitter first.png | Bin ...ershipPairingLockup_Templates_Helvetica.ai | Bin .../twitter/twitter-spaces-12152021.zip | Bin .../__MACOSX/._twitter-spaces-12152021 | Bin .../__MACOSX/twitter-spaces-12152021/._EPS | Bin .../__MACOSX/twitter-spaces-12152021/._PNG | Bin .../__MACOSX/twitter-spaces-12152021/._PSD | Bin .../__MACOSX/twitter-spaces-12152021/._SVG | Bin ...witterspaces-external-playbook-dec2021.pdf | Bin .../EPS/._2021 TwitterSpaces Logo - black.eps | Bin .../EPS/._2021 TwitterSpaces Logo - blue.eps | Bin .../EPS/._2021 TwitterSpaces Logo - white.eps | Bin .../PNG/._2021 TwitterSpaces Logo - black.png | Bin .../PNG/._2021 TwitterSpaces Logo - blue.png | Bin .../PNG/._2021 TwitterSpaces Logo - white.png | Bin .../PSD/._2021 TwitterSpaces Logo - black.psd | Bin .../PSD/._2021 TwitterSpaces Logo - blue.psd | Bin .../PSD/._2021 TwitterSpaces Logo - white.psd | Bin .../SVG/._2021 TwitterSpaces Logo - black.svg | Bin .../SVG/._2021 TwitterSpaces Logo - blue.svg | Bin .../SVG/._2021 TwitterSpaces Logo - white.svg | Bin .../EPS/2021 TwitterSpaces Logo - black.eps | Bin .../EPS/2021 TwitterSpaces Logo - blue.eps | Bin .../EPS/2021 TwitterSpaces Logo - white.eps | Bin .../PNG/2021 TwitterSpaces Logo - black.png | Bin .../PNG/2021 TwitterSpaces Logo - blue.png | Bin .../PNG/2021 TwitterSpaces Logo - white.png | Bin .../PSD/2021 TwitterSpaces Logo - black.psd | Bin .../PSD/2021 TwitterSpaces Logo - blue.psd | Bin .../PSD/2021 TwitterSpaces Logo - white.psd | Bin .../SVG/2021 TwitterSpaces Logo - black.svg | 0 .../SVG/2021 TwitterSpaces Logo - blue.svg | 0 .../SVG/2021 TwitterSpaces Logo - white.svg | 0 ...witterspaces-external-playbook-dec2021.pdf | Bin ...tter-tweet-template-helvetica-01272021.zip | Bin ...2021 Twitter Tweet template - Helvetica.ai | 0 .../Fonts/HelveticaNeueLTPro-55Roman.otf | Bin .../Fonts/HelveticaNeueLTPro-75Bold.otf | Bin .../._Twitter Tweet template - Helvetica | Bin ...2021 Twitter Tweet template - Helvetica.ai | Bin .../._Fonts | Bin .../Fonts/._HelveticaNeueLTPro-55Roman.otf | Bin .../Fonts/._HelveticaNeueLTPro-75Bold.otf | Bin .../lib/organizations/twitter/x/x-logo.zip | Bin .../x/x-logo/__MACOSX/._logo-black.png | Bin .../x/x-logo/__MACOSX/._logo-white.png | Bin .../twitter/x/x-logo/__MACOSX/._logo.svg | Bin .../twitter/x/x-logo/logo-black.png | Bin .../twitter/x/x-logo/logo-white.png | Bin .../organizations/twitter/x/x-logo/logo.svg | 0 .../src}/lib/organizations/wasm/371632.svg | 0 .../lib/organizations/wasm/file-type-wasm.svg | 0 .../organizations/wasm/webassembly (1).svg | 0 .../organizations/wasm/webassembly-icon.png | Bin .../organizations/wasm/webassembly-icon.svg | 0 .../wasm/webassembly.256x256.png | Bin .../lib/organizations/wasm/webassembly.svg | 0 .../wolfram-institute/channels4_profile.jpg | Bin .../YouTube_full-color_icon_(2017).svg | 0 .../youtube/brand-full-color-dark-logo.zip | Bin .../__MACOSX/._youtube_full_color_dark_logo | Bin .../._digital_and_tv | Bin .../youtube_full_color_dark_logo/._print | Bin .../digital_and_tv/._yt_logo_rgb_dark.ai | Bin .../digital_and_tv/._yt_logo_rgb_dark.eps | Bin .../digital_and_tv/._yt_logo_rgb_dark.png | Bin .../print/._yt_logo_cmyk_dark.ai | Bin .../print/._yt_logo_cmyk_dark.eps | Bin .../print/._yt_logo_pms_dark.ai | Bin .../print/._yt_logo_pms_dark.eps | Bin .../digital_and_tv/yt_logo_rgb_dark.ai | 0 .../digital_and_tv/yt_logo_rgb_dark.eps | Bin .../digital_and_tv/yt_logo_rgb_dark.png | Bin .../print/yt_logo_cmyk_dark.ai | 0 .../print/yt_logo_cmyk_dark.eps | Bin .../print/yt_logo_pms_dark.ai | 0 .../print/yt_logo_pms_dark.eps | Bin .../youtube/brand-full-color-light-logo.zip | Bin .../__MACOSX/._youtube_full_color_light_logo | Bin .../._digital_and_tv | Bin .../youtube_full_color_light_logo/._print | Bin .../digital_and_tv/._yt_logo_rgb_light.ai | Bin .../digital_and_tv/._yt_logo_rgb_light.eps | Bin .../digital_and_tv/._yt_logo_rgb_light.png | Bin .../print/._yt_logo_cmyk_light.ai | Bin .../print/._yt_logo_cmyk_light.eps | Bin .../print/._yt_logo_pms_light.ai | Bin .../print/._yt_logo_pms_light.eps | Bin .../digital_and_tv/yt_logo_rgb_light.ai | 0 .../digital_and_tv/yt_logo_rgb_light.eps | Bin .../digital_and_tv/yt_logo_rgb_light.png | Bin .../print/yt_logo_cmyk_light.ai | 0 .../print/yt_logo_cmyk_light.eps | Bin .../print/yt_logo_pms_light.ai | 0 .../print/yt_logo_pms_light.eps | Bin .../youtube/brand-monochrome-logos.zip | Bin .../__MACOSX/._youtube_monochrome_logos | Bin .../youtube_monochrome_logos/._digital_and_tv | Bin .../__MACOSX/youtube_monochrome_logos/._print | Bin .../digital_and_tv/._yt_logo_mono_dark.ai | Bin .../digital_and_tv/._yt_logo_mono_dark.eps | Bin .../digital_and_tv/._yt_logo_mono_dark.png | Bin .../digital_and_tv/._yt_logo_mono_light.ai | Bin .../digital_and_tv/._yt_logo_mono_light.eps | Bin .../digital_and_tv/._yt_logo_mono_light.png | Bin .../print/._yt_logo_cmyk_mono_dark.ai | Bin .../print/._yt_logo_cmyk_mono_dark.eps | Bin .../print/._yt_logo_cmyk_mono_light.ai | Bin .../print/._yt_logo_cmyk_mono_light.eps | Bin .../print/._yt_logo_pms_mono_dark.ai | Bin .../print/._yt_logo_pms_mono_dark.eps | Bin .../print/._yt_logo_pms_mono_light.ai | Bin .../print/._yt_logo_pms_mono_light.eps | Bin .../digital_and_tv/yt_logo_mono_dark.ai | 0 .../digital_and_tv/yt_logo_mono_dark.eps | Bin .../digital_and_tv/yt_logo_mono_dark.png | Bin .../digital_and_tv/yt_logo_mono_light.ai | 0 .../digital_and_tv/yt_logo_mono_light.eps | Bin .../digital_and_tv/yt_logo_mono_light.png | Bin .../print/yt_logo_cmyk_mono_dark.ai | 0 .../print/yt_logo_cmyk_mono_dark.eps | Bin .../print/yt_logo_cmyk_mono_light.ai | 0 .../print/yt_logo_cmyk_mono_light.eps | Bin .../print/yt_logo_pms_mono_dark.ai | 0 .../print/yt_logo_pms_mono_dark.eps | Bin .../print/yt_logo_pms_mono_light.ai | 0 .../print/yt_logo_pms_mono_light.eps | Bin .../youtube/youtube-app-white-icon.svg | 0 .../youtube/youtube-logo-2431.svg | 0 .../organizations/zulip/Zulip-icon-square.svg | 0 .../src}/lib/paper/Paper.tsx | 0 .../src}/lib/paper/PaperContent.tsx | 0 .../src}/lib/paper/browser/Exports.tsx | 0 .../src}/lib/paper/layout/Arc.tsx | 0 .../src}/lib/paper/layout/Author.tsx | 0 .../src}/lib/paper/layout/BR.tsx | 0 .../src}/lib/paper/layout/Link.tsx | 0 .../src}/lib/paper/layout/Organization.tsx | 0 .../src}/lib/paper/layout/Paragraph.tsx | 0 .../src}/lib/paper/layout/Reference.tsx | 0 .../src}/lib/paper/layout/Section.tsx | 0 .../src}/lib/paper/layout/TODO.tsx | 0 .../src}/lib/paper/views/Browser.tsx | 0 .../src}/lib/paper/views/ExportablePaper.tsx | 0 .../src}/lib/pdf/DereferenceHtml.tsx | 0 .../src}/lib/pdf/computeExplicitStyles.tsx | 0 .../src}/lib/pdf/dereferenceHtmlElement.tsx | 0 .../lib/syntax-highlighting/CodeBlock.tsx | 0 .../src}/lib/typescript/React.tsx | 0 .../src}/lib/typescript/Replacer.ts | 0 {src => orbitmines.com/src}/modules.d.ts | 0 .../src}/profiles/FadiShawki/FadiShawki.ts | 0 .../src}/profiles/FadiShawki/FadiShawki2.tsx | 0 .../FadiShawki/fadishawki.profile-picture.png | Bin .../src}/profiles/Profile.tsx | 0 .../src}/profiles/profiles.ts | 0 {src => orbitmines.com/src}/routes/Error.tsx | 0 {src => orbitmines.com/src}/routes/Paper.tsx | 0 .../src}/routes/Profiles.tsx | 0 {src => orbitmines.com/src}/routes/Root.tsx | 0 .../routes/papers/2022.OnIntelligibility.tsx | 0 .../src}/routes/papers/2023.FadiShawki.tsx | 0 .../src}/routes/papers/2023.OnOrbits.tsx | 0 tsconfig.json => orbitmines.com/tsconfig.json | 0 .../useless_junk}/generate_chyp.js | 0 1200 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 .gitignore rename .npmrc => orbitmines.com/.npmrc (100%) rename Dockerfile => orbitmines.com/Dockerfile (100%) rename {build => orbitmines.com/build}/asset-manifest.json (100%) rename {build => orbitmines.com/build}/favicon.png (100%) rename {build => orbitmines.com/build}/index.html (100%) rename {build => orbitmines.com/build}/logo.png (100%) rename {build => orbitmines.com/build}/manifest.json (100%) rename {build => orbitmines.com/build}/papers/on-intelligibility.jpeg (100%) rename {build => orbitmines.com/build}/papers/on-intelligibility.pdf (100%) rename {build => orbitmines.com/build}/papers/sitemap.xml (100%) rename {build => orbitmines.com/build}/profiles/fadi-shawki.jpeg (100%) rename {build => orbitmines.com/build}/profiles/fadi-shawki.pdf (100%) rename {build => orbitmines.com/build}/profiles/fadi-shawki/profile-picture.jpg (100%) rename {build => orbitmines.com/build}/profiles/sitemap.xml (100%) rename {build => orbitmines.com/build}/robots.txt (100%) rename {build => orbitmines.com/build}/sitemap.xml (100%) rename {build => orbitmines.com/build}/static/css/main.f3c29dcc.css (100%) rename {build => orbitmines.com/build}/static/css/main.f3c29dcc.css.map (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-16px-paths.e600f430.chunk.js (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-16px-paths.e600f430.chunk.js.map (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js.map (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js.map (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js.map (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js (100%) rename {build => orbitmines.com/build}/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js.map (100%) rename {build => orbitmines.com/build}/static/js/main.a4bd6e59.js (100%) rename {build => orbitmines.com/build}/static/js/main.a4bd6e59.js.LICENSE.txt (100%) rename {build => orbitmines.com/build}/static/js/main.a4bd6e59.js.map (100%) rename {build => orbitmines.com/build}/static/media/JetBrainsMono-Bold.a490f58c0f460cdc1a8d.ttf (100%) rename {build => orbitmines.com/build}/static/media/JetBrainsMono-Regular.73fb7b7f0e68b372adfe.ttf (100%) rename {build => orbitmines.com/build}/static/media/JetBrainsMono-SemiBold.6c00e23bc7910a97f8e8.ttf (100%) rename {build => orbitmines.com/build}/static/media/Logo-NGI_Icon-circle-NGI-rgb.c187053ac056096e2c8f.png (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-16.a06729235b0be3c89599.eot (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-16.a3184b43073d6a13b0ff.svg (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-16.e7a60f2ff401d5c92c24.ttf (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-16.ed58254a5b3bcbb792c0.woff (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-16.f313e46860f341decc69.woff2 (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-20.2417badadcf0d0550bf7.eot (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-20.44fac984317ccf8ffc81.ttf (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-20.6b3b37d0b8765e8789ad.svg (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-20.73d7a30f5fc31bef9177.woff2 (100%) rename {build => orbitmines.com/build}/static/media/blueprint-icons-20.8f34eccd1505822c8837.woff (100%) rename {build => orbitmines.com/build}/static/media/channels4_profile.fa1b005883d06175e760.jpg (100%) rename {build => orbitmines.com/build}/static/media/orbitmines.icon.650x650.81a851f37d449e32d039.png (100%) rename {build => orbitmines.com/build}/static/media/orbitmines.logo.3000x1000.e3b652e472c9565f6f93.png (100%) rename {build => orbitmines.com/build}/static/media/semf_icon.074319a62dc1fe56a243.jpg (100%) rename {build => orbitmines.com/build}/static/media/strange_loop_logo_final_color_no_year_square2.c44a51529852563fffb8.png (100%) rename {build => orbitmines.com/build}/static/media/topos_favicon.edde03404c314a2f6347.ico (100%) rename config-overrides.js => orbitmines.com/config-overrides.js (100%) rename package-lock.json => orbitmines.com/package-lock.json (100%) rename package.json => orbitmines.com/package.json (100%) rename {public => orbitmines.com/public}/favicon.png (100%) rename {public => orbitmines.com/public}/index.html (100%) rename {public => orbitmines.com/public}/logo.png (100%) rename {public => orbitmines.com/public}/manifest.json (100%) rename {public => orbitmines.com/public}/papers/on-intelligibility.jpeg (100%) rename {public => orbitmines.com/public}/papers/on-intelligibility.pdf (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies.jpeg (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies.pdf (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/0_1.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/0_1_tilted.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_2_select_1.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_expanded.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_selected.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_2.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_double_expanded_continuation.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0_teleporting.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1_teleporting.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_selected.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_with_equivs.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation_selected.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary_loops.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_loop_2_select_1.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_orange.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_0.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_1.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_superposition.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_binary.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_pink.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/3.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/3_expanded_continuation.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/3_fractal.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/3_select_0.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/3_tertiary.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_grid.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_seperated.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_unordered.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/branch.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/branch_expanded.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex_green.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/header.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/naked_point.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/some_structure.png (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/1920x1080.jpeg (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/3840x2160.jpeg (100%) rename {public => orbitmines.com/public}/papers/on-orbits-equivalence-and-inconsistencies/images/two_vertices.png (100%) rename {public => orbitmines.com/public}/papers/sitemap.xml (100%) rename {public => orbitmines.com/public}/profiles/fadi-shawki.jpeg (100%) rename {public => orbitmines.com/public}/profiles/fadi-shawki.pdf (100%) rename {public => orbitmines.com/public}/profiles/fadi-shawki/profile-picture.jpg (100%) rename {public => orbitmines.com/public}/profiles/sitemap.xml (100%) rename {public => orbitmines.com/public}/robots.txt (100%) rename {public => orbitmines.com/public}/sitemap.xml (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/JS.spec.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/JS.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/JS2.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/OrbitMinesExplorer.tsx (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/REFACTOR_RENDER.md (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/Ray.spec.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/Ray.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/Ray2.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/Visualization.tsx (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/debug/DebugCanvas.tsx (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx (100%) rename {src => orbitmines.com/src}/@orbitmines/explorer/errors/errors.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/external/chyp/Chyp.spec.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/external/chyp/Chyp.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/external/chyp/ChypCanvas.tsx (100%) rename {src => orbitmines.com/src}/@orbitmines/external/chyp/Chyp_naive_pass.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/external/chyp/README.md (100%) rename {src => orbitmines.com/src}/@orbitmines/external/chyp/examples.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/js/react/IEventListener.tsx (100%) rename {src => orbitmines.com/src}/@orbitmines/js/react/IModule.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/js/react/Modules.tsx (100%) rename {src => orbitmines.com/src}/@orbitmines/js/react/hooks/useHotkeys.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/js/react/hooks/useHovering.ts (100%) rename {src => orbitmines.com/src}/@orbitmines/rays/index.ts (100%) rename {src => orbitmines.com/src}/App.tsx (100%) rename {src => orbitmines.com/src}/index.tsx (100%) rename {src => orbitmines.com/src}/lib/index.ts (100%) rename {src => orbitmines.com/src}/lib/layout/experimental-designs/BlueprintJS.tsx (100%) rename {src => orbitmines.com/src}/lib/layout/experimental-designs/Icons.tsx (100%) rename {src => orbitmines.com/src}/lib/layout/experimental-designs/Legacy.tsx (100%) rename {src => orbitmines.com/src}/lib/layout/flexbox/Col.tsx (100%) rename {src => orbitmines.com/src}/lib/layout/flexbox/Grid.tsx (100%) rename {src => orbitmines.com/src}/lib/layout/flexbox/Row.tsx (100%) rename {src => orbitmines.com/src}/lib/layout/flexbox/constants.ts (100%) rename {src => orbitmines.com/src}/lib/layout/flexbox/index.ts (100%) rename {src => orbitmines.com/src}/lib/layout/flexbox/styles/flexbox.scss (100%) rename {src => orbitmines.com/src}/lib/layout/font/Font.tsx (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono-2.242.zip (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono.ts (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Italic.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Regular.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Italic.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Regular.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL_Regular.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Italic.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Regular.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Italic.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Regular.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono_Regular.json (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Bold.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-BoldItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBold.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBoldItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLight.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLightItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Italic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Light.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-LightItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Medium.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-MediumItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Regular.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBold.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBoldItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Thin.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ThinItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Bold.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-BoldItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBold.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBoldItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLight.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLightItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Italic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Light.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-LightItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Medium.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-MediumItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Regular.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBold.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBoldItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Thin.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ThinItalic.ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono-Italic[wght].ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono[wght].ttf (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Bold.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-BoldItalic.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBold.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBoldItalic.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLight.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLightItalic.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Italic.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Light.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-LightItalic.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Medium.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-MediumItalic.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Regular.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBold.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBoldItalic.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Thin.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ThinItalic.woff2 (100%) rename {src => orbitmines.com/src}/lib/layout/font/styles/font.scss (100%) rename {src => orbitmines.com/src}/lib/layout/icons/CustomIcon.tsx (100%) rename {src => orbitmines.com/src}/lib/layout/styles/blueprintjs/styles/blueprintjs.scss (100%) rename {src => orbitmines.com/src}/lib/layout/styles/index.scss (100%) rename {src => orbitmines.com/src}/lib/layout/styles/spacing.scss (100%) rename {src => orbitmines.com/src}/lib/organizations/3b1b/3B1B_Logo.svg.png (100%) rename {src => orbitmines.com/src}/lib/organizations/ORGANIZATIONS.ts (100%) rename {src => orbitmines.com/src}/lib/organizations/README.md (100%) rename {src => orbitmines.com/src}/lib/organizations/akissinger/881183.png (100%) rename {src => orbitmines.com/src}/lib/organizations/critical-thinking/he8VyFCv_400x400.jpg (100%) rename {src => orbitmines.com/src}/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.avif (100%) rename {src => orbitmines.com/src}/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.png (100%) rename {src => orbitmines.com/src}/lib/organizations/discord/discord-mark-white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/fission.codes/d399fc1f178d48c7b9f775ed1f6b9a4ff5f851c2.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.png (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/GitHub-Logos/README.txt (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/__MACOSX/._GitHub-Logos (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.png (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._README.txt (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark/__MACOSX/._github-mark (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.png (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark/github-mark/github-mark-white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark/github-mark/github-mark-white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark/github-mark/github-mark.png (100%) rename {src => orbitmines.com/src}/lib/organizations/github/github-mark/github-mark/github-mark.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/gitlab.com/gitlab-logo-700.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/hoc/92327702.png (100%) rename {src => orbitmines.com/src}/lib/organizations/hoc/Favicon.png (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.jpg (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.png (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.jpg (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.png (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient_RGB.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.jpg (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/ipfs/ipfs.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/joinmastodon.org/logo-black.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/joinmastodon.org/logo-purple.png (100%) rename {src => orbitmines.com/src}/lib/organizations/joinmastodon.org/logo-purple.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/lexfridman-podcast/download.jpeg (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/LinkedIn-Logos.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/LinkedIn-Logos/LI-In-Bug.png (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/LinkedIn-Logos/LI-Logo.png (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos.zip (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\342\224\254\302\253@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\342\224\254\302\253@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/._LinkedIn-Logos (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._In (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._Logo (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Digital (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Print (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._Blue (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._White (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._1x (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._2x (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96@2x.png (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._1x (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._2x (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\316\223\303\244\303\263.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\316\223\303\244\303\263.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\342\224\254\302\253.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\342\224\254\302\253.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96@2x.png (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._CMYK (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._PMS (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._Blue (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._White (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Digital (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Print (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/._Blue (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/._2x (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\342\224\254\302\253@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40@2x.png (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\342\224\254\302\253@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\342\224\254\302\253@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\342\224\254\302\253@2x.png" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96@2x.png (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._CMYK (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._PMS (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._Blue (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._White (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M.eps (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" (100%) rename "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" => "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/linkedin/linkedin-svgrepo-com.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Facebook-Brand-Asset-Pack.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.jpg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Black/Digital_Glyph_Black.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Dark Green/Digital_Glyph_Dark_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Green/Digital_Glyph_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/White/Digital_Glyph_White.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Black/Digital_Glyph_Black.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Dark Green/Digital_Glyph_Dark_Green.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Green/Digital_Glyph_Green.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/White/Digital_Glyph_White.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Black/Digital_Glyph_Black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Dark Green/Digital_Glyph_Dark_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Green/Digital_Glyph_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/White/Digital_Glyph_White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Black/Print_Glyph_Black.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Dark Green/Print_Glyph_Dark_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Green/Print_Glyph_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/White/Print_Glyph_White.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Black/Print_Glyph_Black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Dark Green/Print_Glyph_Dark_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Green/Print_Glyph_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/White/Print_Glyph_White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Black/Digital_Inline_Black.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Dark Green/Digital_Inline_Dark_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Green/Digital_Inline_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/White/Digital_Inline_White.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Black/Digital_Inline_Black.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Dark Green/Digital_Inline_Dark_Green.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Green/Digital_Inline_Green.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/White/Digital_Inline_White.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Black/Digital_Inline_Black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Dark Green/Digital_Inline_Dark_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Green/Digital_Inline_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/White/Digital_Inline_White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Black/Print_Inline_Black.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Dark Green/Print_Inline_Dark_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Green/Print_Inline_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/White/Print_Inline_White.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Black/Print_Inline_Black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Dark Green/Print_Inline_Dark_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Green/Print_Inline_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/White/Print_Inline_White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Black/Digital_Stacked_Black.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Dark Green/Digital_Stacked_Dark_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Green/Digital_Stacked_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/White/Digital_Stacked_White.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Black/Digital_Stacked_Black.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Dark Green/Digital_Stacked_Dark_Green.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Green/Digital_Stacked_Green.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/White/Digital_Stacked_White.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Black/Digital_Stacked_Black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Dark Green/Digital_Stacked_Dark_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Green/Digital_Stacked_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/White/Digital_Stacked_White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Black/Print_Stacked_Black.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Dark Green/Print_Stacked_Dark_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Green/Print_Stacked_Green.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/White/Print_Stacked_White.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Black/Print_Stacked_Black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Dark Green/Print_Stacked_Dark_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Green/Print_Stacked_Green.png (100%) rename {src => orbitmines.com/src}/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/White/Print_Stacked_White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/mlst/channels4_profile.jpg (100%) rename {src => orbitmines.com/src}/lib/organizations/ngi/Logo-NGI_Icon-circle-NGI-rgb.png (100%) rename {src => orbitmines.com/src}/lib/organizations/nixos/nixos-icon.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.16x16.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.64x64.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.734x720.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.2.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/icon/orbitmines.icon.64x64.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.min.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.2000x419.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3436x720.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3800x634.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/logo/orbitmines.logo.2048x1152.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/logo/orbitmines.logo.3000x1000.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.16x15.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.848x782.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.16x15.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.848x782.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.16x15.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.848x782.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.16x15.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.848x782.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.creative.1000x1000.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.1000x1000.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.2.1000x1000.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.kitpvp.1000x1000.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.minigames.1000x1000.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.prison.1000x1000.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.skyblock.1000x1000.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.survival.1000x1000.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.creative.1000x300.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.fog.1000x300.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.kitpvp.1000x300.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.minigames.1000x300.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.prison.1000x300.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.skyblock.1000x300.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.survival.1000x300.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-32x32.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.gif (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-vector.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon-vector.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_128x128.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_24x24.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_32x32.png (100%) rename {src => orbitmines.com/src}/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_vector.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/papers-we-love/6187757.png (100%) rename {src => orbitmines.com/src}/lib/organizations/preposterous-universe/download.jpeg (100%) rename {src => orbitmines.com/src}/lib/organizations/santa-fe-institute/0_OgRM7UU-SsqK46La.png (100%) rename {src => orbitmines.com/src}/lib/organizations/semf/semf_icon.jpg (100%) rename {src => orbitmines.com/src}/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square.jpg (100%) rename {src => orbitmines.com/src}/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.png (100%) rename {src => orbitmines.com/src}/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.xcf (100%) create mode 100644 orbitmines.com/src/lib/organizations/temp.ts rename {src => orbitmines.com/src}/lib/organizations/tinycorp/132956020.jpeg (100%) rename {src => orbitmines.com/src}/lib/organizations/topos.institute/topos_favicon.ico (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ase (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Guidelines (Speedrun Edition)/Twitch_Guidelines_Speedrun_v2.pdf (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch-Wordmark-BlackOps.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple-01.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/._Brand Assets (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Color Palette (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Guidelines (Speedrun Edition) (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Logos (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ase (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Guidelines (Speedrun Edition)/._Twitch_Guidelines_Speedrun_v2.pdf (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._glitch (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._wordmark (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Black Ops (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Purple (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._White (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Extruded Wordmark (Primary Logo) (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Wordmark (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Black Ops (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Twitch Purple (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Black Ops (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Twitch Purple (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._White (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch-Wordmark-BlackOps.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple-01.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitch/twitch-white-icon.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - black.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - black.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo black.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter logo (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter social icons (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._EPS (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PNG (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PSD (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._SVG (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - black.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - black.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo black.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - circle (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - rounded square (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - square (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/PartnershipPairingLockup_Templates_Helvetica.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/._Twitter partnership lockups (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._PartnershipPairingLockup_Templates_Helvetica.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/._twitter-spaces-12152021 (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._EPS (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PNG (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PSD (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._SVG (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._twitterspaces-external-playbook-dec2021.pdf (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - black.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - black.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - black.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - black.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - blue.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - white.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - blue.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - black.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - blue.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - white.psd (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - black.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - blue.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - white.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/twitterspaces-external-playbook-dec2021.pdf (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/2021 Twitter Tweet template - Helvetica.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-55Roman.otf (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-75Bold.otf (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/._Twitter Tweet template - Helvetica (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._2021 Twitter Tweet template - Helvetica.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._Fonts (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-55Roman.otf (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-75Bold.otf (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/x/x-logo.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/x/x-logo/__MACOSX/._logo.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/x/x-logo/logo-black.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/x/x-logo/logo-white.png (100%) rename {src => orbitmines.com/src}/lib/organizations/twitter/x/x-logo/logo.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/wasm/371632.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/wasm/file-type-wasm.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/wasm/webassembly (1).svg (100%) rename {src => orbitmines.com/src}/lib/organizations/wasm/webassembly-icon.png (100%) rename {src => orbitmines.com/src}/lib/organizations/wasm/webassembly-icon.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/wasm/webassembly.256x256.png (100%) rename {src => orbitmines.com/src}/lib/organizations/wasm/webassembly.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/wolfram-institute/channels4_profile.jpg (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/YouTube_full-color_icon_(2017).svg (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/._youtube_full_color_dark_logo (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._digital_and_tv (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._print (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.png (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.png (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/._youtube_full_color_light_logo (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._digital_and_tv (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._print (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.png (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.png (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos.zip (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/._youtube_monochrome_logos (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._digital_and_tv (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._print (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.png (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.png (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.png (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.png (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.ai (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.eps (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/youtube-app-white-icon.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/youtube/youtube-logo-2431.svg (100%) rename {src => orbitmines.com/src}/lib/organizations/zulip/Zulip-icon-square.svg (100%) rename {src => orbitmines.com/src}/lib/paper/Paper.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/PaperContent.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/browser/Exports.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/layout/Arc.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/layout/Author.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/layout/BR.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/layout/Link.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/layout/Organization.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/layout/Paragraph.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/layout/Reference.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/layout/Section.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/layout/TODO.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/views/Browser.tsx (100%) rename {src => orbitmines.com/src}/lib/paper/views/ExportablePaper.tsx (100%) rename {src => orbitmines.com/src}/lib/pdf/DereferenceHtml.tsx (100%) rename {src => orbitmines.com/src}/lib/pdf/computeExplicitStyles.tsx (100%) rename {src => orbitmines.com/src}/lib/pdf/dereferenceHtmlElement.tsx (100%) rename {src => orbitmines.com/src}/lib/syntax-highlighting/CodeBlock.tsx (100%) rename {src => orbitmines.com/src}/lib/typescript/React.tsx (100%) rename {src => orbitmines.com/src}/lib/typescript/Replacer.ts (100%) rename {src => orbitmines.com/src}/modules.d.ts (100%) rename {src => orbitmines.com/src}/profiles/FadiShawki/FadiShawki.ts (100%) rename {src => orbitmines.com/src}/profiles/FadiShawki/FadiShawki2.tsx (100%) rename {src => orbitmines.com/src}/profiles/FadiShawki/fadishawki.profile-picture.png (100%) rename {src => orbitmines.com/src}/profiles/Profile.tsx (100%) rename {src => orbitmines.com/src}/profiles/profiles.ts (100%) rename {src => orbitmines.com/src}/routes/Error.tsx (100%) rename {src => orbitmines.com/src}/routes/Paper.tsx (100%) rename {src => orbitmines.com/src}/routes/Profiles.tsx (100%) rename {src => orbitmines.com/src}/routes/Root.tsx (100%) rename {src => orbitmines.com/src}/routes/papers/2022.OnIntelligibility.tsx (100%) rename {src => orbitmines.com/src}/routes/papers/2023.FadiShawki.tsx (100%) rename {src => orbitmines.com/src}/routes/papers/2023.OnOrbits.tsx (100%) rename tsconfig.json => orbitmines.com/tsconfig.json (100%) rename {useless_junk => orbitmines.com/useless_junk}/generate_chyp.js (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 20be79e..ef35695 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,5 +10,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v3 - - run: npm install - - run: npm run test -- --watchAll=false \ No newline at end of file + - working-directory: "./orbitmines.com" + run: npm install + - working-directory: "./orbitmines.com" + run: npm run test -- --watchAll=false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..02be175 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Miscellaneous +external + +# orbitmines.com +orbitmines.com/node_modules + +# Environment +.idea + diff --git a/.npmrc b/orbitmines.com/.npmrc similarity index 100% rename from .npmrc rename to orbitmines.com/.npmrc diff --git a/Dockerfile b/orbitmines.com/Dockerfile similarity index 100% rename from Dockerfile rename to orbitmines.com/Dockerfile diff --git a/build/asset-manifest.json b/orbitmines.com/build/asset-manifest.json similarity index 100% rename from build/asset-manifest.json rename to orbitmines.com/build/asset-manifest.json diff --git a/build/favicon.png b/orbitmines.com/build/favicon.png similarity index 100% rename from build/favicon.png rename to orbitmines.com/build/favicon.png diff --git a/build/index.html b/orbitmines.com/build/index.html similarity index 100% rename from build/index.html rename to orbitmines.com/build/index.html diff --git a/build/logo.png b/orbitmines.com/build/logo.png similarity index 100% rename from build/logo.png rename to orbitmines.com/build/logo.png diff --git a/build/manifest.json b/orbitmines.com/build/manifest.json similarity index 100% rename from build/manifest.json rename to orbitmines.com/build/manifest.json diff --git a/build/papers/on-intelligibility.jpeg b/orbitmines.com/build/papers/on-intelligibility.jpeg similarity index 100% rename from build/papers/on-intelligibility.jpeg rename to orbitmines.com/build/papers/on-intelligibility.jpeg diff --git a/build/papers/on-intelligibility.pdf b/orbitmines.com/build/papers/on-intelligibility.pdf similarity index 100% rename from build/papers/on-intelligibility.pdf rename to orbitmines.com/build/papers/on-intelligibility.pdf diff --git a/build/papers/sitemap.xml b/orbitmines.com/build/papers/sitemap.xml similarity index 100% rename from build/papers/sitemap.xml rename to orbitmines.com/build/papers/sitemap.xml diff --git a/build/profiles/fadi-shawki.jpeg b/orbitmines.com/build/profiles/fadi-shawki.jpeg similarity index 100% rename from build/profiles/fadi-shawki.jpeg rename to orbitmines.com/build/profiles/fadi-shawki.jpeg diff --git a/build/profiles/fadi-shawki.pdf b/orbitmines.com/build/profiles/fadi-shawki.pdf similarity index 100% rename from build/profiles/fadi-shawki.pdf rename to orbitmines.com/build/profiles/fadi-shawki.pdf diff --git a/build/profiles/fadi-shawki/profile-picture.jpg b/orbitmines.com/build/profiles/fadi-shawki/profile-picture.jpg similarity index 100% rename from build/profiles/fadi-shawki/profile-picture.jpg rename to orbitmines.com/build/profiles/fadi-shawki/profile-picture.jpg diff --git a/build/profiles/sitemap.xml b/orbitmines.com/build/profiles/sitemap.xml similarity index 100% rename from build/profiles/sitemap.xml rename to orbitmines.com/build/profiles/sitemap.xml diff --git a/build/robots.txt b/orbitmines.com/build/robots.txt similarity index 100% rename from build/robots.txt rename to orbitmines.com/build/robots.txt diff --git a/build/sitemap.xml b/orbitmines.com/build/sitemap.xml similarity index 100% rename from build/sitemap.xml rename to orbitmines.com/build/sitemap.xml diff --git a/build/static/css/main.f3c29dcc.css b/orbitmines.com/build/static/css/main.f3c29dcc.css similarity index 100% rename from build/static/css/main.f3c29dcc.css rename to orbitmines.com/build/static/css/main.f3c29dcc.css diff --git a/build/static/css/main.f3c29dcc.css.map b/orbitmines.com/build/static/css/main.f3c29dcc.css.map similarity index 100% rename from build/static/css/main.f3c29dcc.css.map rename to orbitmines.com/build/static/css/main.f3c29dcc.css.map diff --git a/build/static/js/blueprint-icons-16px-paths.e600f430.chunk.js b/orbitmines.com/build/static/js/blueprint-icons-16px-paths.e600f430.chunk.js similarity index 100% rename from build/static/js/blueprint-icons-16px-paths.e600f430.chunk.js rename to orbitmines.com/build/static/js/blueprint-icons-16px-paths.e600f430.chunk.js diff --git a/build/static/js/blueprint-icons-16px-paths.e600f430.chunk.js.map b/orbitmines.com/build/static/js/blueprint-icons-16px-paths.e600f430.chunk.js.map similarity index 100% rename from build/static/js/blueprint-icons-16px-paths.e600f430.chunk.js.map rename to orbitmines.com/build/static/js/blueprint-icons-16px-paths.e600f430.chunk.js.map diff --git a/build/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js b/orbitmines.com/build/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js similarity index 100% rename from build/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js rename to orbitmines.com/build/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js diff --git a/build/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js.map b/orbitmines.com/build/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js.map similarity index 100% rename from build/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js.map rename to orbitmines.com/build/static/js/blueprint-icons-20px-paths.aea2767b.chunk.js.map diff --git a/build/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js b/orbitmines.com/build/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js similarity index 100% rename from build/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js rename to orbitmines.com/build/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js diff --git a/build/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js.map b/orbitmines.com/build/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js.map similarity index 100% rename from build/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js.map rename to orbitmines.com/build/static/js/blueprint-icons-all-paths-loader.03d11c89.chunk.js.map diff --git a/build/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js b/orbitmines.com/build/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js similarity index 100% rename from build/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js rename to orbitmines.com/build/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js diff --git a/build/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js.map b/orbitmines.com/build/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js.map similarity index 100% rename from build/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js.map rename to orbitmines.com/build/static/js/blueprint-icons-all-paths.ebc06bc3.chunk.js.map diff --git a/build/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js b/orbitmines.com/build/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js similarity index 100% rename from build/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js rename to orbitmines.com/build/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js diff --git a/build/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js.map b/orbitmines.com/build/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js.map similarity index 100% rename from build/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js.map rename to orbitmines.com/build/static/js/blueprint-icons-split-paths-by-size-loader.28faa981.chunk.js.map diff --git a/build/static/js/main.a4bd6e59.js b/orbitmines.com/build/static/js/main.a4bd6e59.js similarity index 100% rename from build/static/js/main.a4bd6e59.js rename to orbitmines.com/build/static/js/main.a4bd6e59.js diff --git a/build/static/js/main.a4bd6e59.js.LICENSE.txt b/orbitmines.com/build/static/js/main.a4bd6e59.js.LICENSE.txt similarity index 100% rename from build/static/js/main.a4bd6e59.js.LICENSE.txt rename to orbitmines.com/build/static/js/main.a4bd6e59.js.LICENSE.txt diff --git a/build/static/js/main.a4bd6e59.js.map b/orbitmines.com/build/static/js/main.a4bd6e59.js.map similarity index 100% rename from build/static/js/main.a4bd6e59.js.map rename to orbitmines.com/build/static/js/main.a4bd6e59.js.map diff --git a/build/static/media/JetBrainsMono-Bold.a490f58c0f460cdc1a8d.ttf b/orbitmines.com/build/static/media/JetBrainsMono-Bold.a490f58c0f460cdc1a8d.ttf similarity index 100% rename from build/static/media/JetBrainsMono-Bold.a490f58c0f460cdc1a8d.ttf rename to orbitmines.com/build/static/media/JetBrainsMono-Bold.a490f58c0f460cdc1a8d.ttf diff --git a/build/static/media/JetBrainsMono-Regular.73fb7b7f0e68b372adfe.ttf b/orbitmines.com/build/static/media/JetBrainsMono-Regular.73fb7b7f0e68b372adfe.ttf similarity index 100% rename from build/static/media/JetBrainsMono-Regular.73fb7b7f0e68b372adfe.ttf rename to orbitmines.com/build/static/media/JetBrainsMono-Regular.73fb7b7f0e68b372adfe.ttf diff --git a/build/static/media/JetBrainsMono-SemiBold.6c00e23bc7910a97f8e8.ttf b/orbitmines.com/build/static/media/JetBrainsMono-SemiBold.6c00e23bc7910a97f8e8.ttf similarity index 100% rename from build/static/media/JetBrainsMono-SemiBold.6c00e23bc7910a97f8e8.ttf rename to orbitmines.com/build/static/media/JetBrainsMono-SemiBold.6c00e23bc7910a97f8e8.ttf diff --git a/build/static/media/Logo-NGI_Icon-circle-NGI-rgb.c187053ac056096e2c8f.png b/orbitmines.com/build/static/media/Logo-NGI_Icon-circle-NGI-rgb.c187053ac056096e2c8f.png similarity index 100% rename from build/static/media/Logo-NGI_Icon-circle-NGI-rgb.c187053ac056096e2c8f.png rename to orbitmines.com/build/static/media/Logo-NGI_Icon-circle-NGI-rgb.c187053ac056096e2c8f.png diff --git a/build/static/media/blueprint-icons-16.a06729235b0be3c89599.eot b/orbitmines.com/build/static/media/blueprint-icons-16.a06729235b0be3c89599.eot similarity index 100% rename from build/static/media/blueprint-icons-16.a06729235b0be3c89599.eot rename to orbitmines.com/build/static/media/blueprint-icons-16.a06729235b0be3c89599.eot diff --git a/build/static/media/blueprint-icons-16.a3184b43073d6a13b0ff.svg b/orbitmines.com/build/static/media/blueprint-icons-16.a3184b43073d6a13b0ff.svg similarity index 100% rename from build/static/media/blueprint-icons-16.a3184b43073d6a13b0ff.svg rename to orbitmines.com/build/static/media/blueprint-icons-16.a3184b43073d6a13b0ff.svg diff --git a/build/static/media/blueprint-icons-16.e7a60f2ff401d5c92c24.ttf b/orbitmines.com/build/static/media/blueprint-icons-16.e7a60f2ff401d5c92c24.ttf similarity index 100% rename from build/static/media/blueprint-icons-16.e7a60f2ff401d5c92c24.ttf rename to orbitmines.com/build/static/media/blueprint-icons-16.e7a60f2ff401d5c92c24.ttf diff --git a/build/static/media/blueprint-icons-16.ed58254a5b3bcbb792c0.woff b/orbitmines.com/build/static/media/blueprint-icons-16.ed58254a5b3bcbb792c0.woff similarity index 100% rename from build/static/media/blueprint-icons-16.ed58254a5b3bcbb792c0.woff rename to orbitmines.com/build/static/media/blueprint-icons-16.ed58254a5b3bcbb792c0.woff diff --git a/build/static/media/blueprint-icons-16.f313e46860f341decc69.woff2 b/orbitmines.com/build/static/media/blueprint-icons-16.f313e46860f341decc69.woff2 similarity index 100% rename from build/static/media/blueprint-icons-16.f313e46860f341decc69.woff2 rename to orbitmines.com/build/static/media/blueprint-icons-16.f313e46860f341decc69.woff2 diff --git a/build/static/media/blueprint-icons-20.2417badadcf0d0550bf7.eot b/orbitmines.com/build/static/media/blueprint-icons-20.2417badadcf0d0550bf7.eot similarity index 100% rename from build/static/media/blueprint-icons-20.2417badadcf0d0550bf7.eot rename to orbitmines.com/build/static/media/blueprint-icons-20.2417badadcf0d0550bf7.eot diff --git a/build/static/media/blueprint-icons-20.44fac984317ccf8ffc81.ttf b/orbitmines.com/build/static/media/blueprint-icons-20.44fac984317ccf8ffc81.ttf similarity index 100% rename from build/static/media/blueprint-icons-20.44fac984317ccf8ffc81.ttf rename to orbitmines.com/build/static/media/blueprint-icons-20.44fac984317ccf8ffc81.ttf diff --git a/build/static/media/blueprint-icons-20.6b3b37d0b8765e8789ad.svg b/orbitmines.com/build/static/media/blueprint-icons-20.6b3b37d0b8765e8789ad.svg similarity index 100% rename from build/static/media/blueprint-icons-20.6b3b37d0b8765e8789ad.svg rename to orbitmines.com/build/static/media/blueprint-icons-20.6b3b37d0b8765e8789ad.svg diff --git a/build/static/media/blueprint-icons-20.73d7a30f5fc31bef9177.woff2 b/orbitmines.com/build/static/media/blueprint-icons-20.73d7a30f5fc31bef9177.woff2 similarity index 100% rename from build/static/media/blueprint-icons-20.73d7a30f5fc31bef9177.woff2 rename to orbitmines.com/build/static/media/blueprint-icons-20.73d7a30f5fc31bef9177.woff2 diff --git a/build/static/media/blueprint-icons-20.8f34eccd1505822c8837.woff b/orbitmines.com/build/static/media/blueprint-icons-20.8f34eccd1505822c8837.woff similarity index 100% rename from build/static/media/blueprint-icons-20.8f34eccd1505822c8837.woff rename to orbitmines.com/build/static/media/blueprint-icons-20.8f34eccd1505822c8837.woff diff --git a/build/static/media/channels4_profile.fa1b005883d06175e760.jpg b/orbitmines.com/build/static/media/channels4_profile.fa1b005883d06175e760.jpg similarity index 100% rename from build/static/media/channels4_profile.fa1b005883d06175e760.jpg rename to orbitmines.com/build/static/media/channels4_profile.fa1b005883d06175e760.jpg diff --git a/build/static/media/orbitmines.icon.650x650.81a851f37d449e32d039.png b/orbitmines.com/build/static/media/orbitmines.icon.650x650.81a851f37d449e32d039.png similarity index 100% rename from build/static/media/orbitmines.icon.650x650.81a851f37d449e32d039.png rename to orbitmines.com/build/static/media/orbitmines.icon.650x650.81a851f37d449e32d039.png diff --git a/build/static/media/orbitmines.logo.3000x1000.e3b652e472c9565f6f93.png b/orbitmines.com/build/static/media/orbitmines.logo.3000x1000.e3b652e472c9565f6f93.png similarity index 100% rename from build/static/media/orbitmines.logo.3000x1000.e3b652e472c9565f6f93.png rename to orbitmines.com/build/static/media/orbitmines.logo.3000x1000.e3b652e472c9565f6f93.png diff --git a/build/static/media/semf_icon.074319a62dc1fe56a243.jpg b/orbitmines.com/build/static/media/semf_icon.074319a62dc1fe56a243.jpg similarity index 100% rename from build/static/media/semf_icon.074319a62dc1fe56a243.jpg rename to orbitmines.com/build/static/media/semf_icon.074319a62dc1fe56a243.jpg diff --git a/build/static/media/strange_loop_logo_final_color_no_year_square2.c44a51529852563fffb8.png b/orbitmines.com/build/static/media/strange_loop_logo_final_color_no_year_square2.c44a51529852563fffb8.png similarity index 100% rename from build/static/media/strange_loop_logo_final_color_no_year_square2.c44a51529852563fffb8.png rename to orbitmines.com/build/static/media/strange_loop_logo_final_color_no_year_square2.c44a51529852563fffb8.png diff --git a/build/static/media/topos_favicon.edde03404c314a2f6347.ico b/orbitmines.com/build/static/media/topos_favicon.edde03404c314a2f6347.ico similarity index 100% rename from build/static/media/topos_favicon.edde03404c314a2f6347.ico rename to orbitmines.com/build/static/media/topos_favicon.edde03404c314a2f6347.ico diff --git a/config-overrides.js b/orbitmines.com/config-overrides.js similarity index 100% rename from config-overrides.js rename to orbitmines.com/config-overrides.js diff --git a/package-lock.json b/orbitmines.com/package-lock.json similarity index 100% rename from package-lock.json rename to orbitmines.com/package-lock.json diff --git a/package.json b/orbitmines.com/package.json similarity index 100% rename from package.json rename to orbitmines.com/package.json diff --git a/public/favicon.png b/orbitmines.com/public/favicon.png similarity index 100% rename from public/favicon.png rename to orbitmines.com/public/favicon.png diff --git a/public/index.html b/orbitmines.com/public/index.html similarity index 100% rename from public/index.html rename to orbitmines.com/public/index.html diff --git a/public/logo.png b/orbitmines.com/public/logo.png similarity index 100% rename from public/logo.png rename to orbitmines.com/public/logo.png diff --git a/public/manifest.json b/orbitmines.com/public/manifest.json similarity index 100% rename from public/manifest.json rename to orbitmines.com/public/manifest.json diff --git a/public/papers/on-intelligibility.jpeg b/orbitmines.com/public/papers/on-intelligibility.jpeg similarity index 100% rename from public/papers/on-intelligibility.jpeg rename to orbitmines.com/public/papers/on-intelligibility.jpeg diff --git a/public/papers/on-intelligibility.pdf b/orbitmines.com/public/papers/on-intelligibility.pdf similarity index 100% rename from public/papers/on-intelligibility.pdf rename to orbitmines.com/public/papers/on-intelligibility.pdf diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies.jpeg b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies.jpeg similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies.jpeg rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies.jpeg diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies.pdf b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies.pdf similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies.pdf rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies.pdf diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/0_1.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/0_1.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/0_1.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/0_1.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/0_1_tilted.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/0_1_tilted.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/0_1_tilted.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/0_1_tilted.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_2_select_1.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_2_select_1.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_2_select_1.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_2_select_1.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_expanded.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_expanded.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_expanded.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_expanded.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_selected.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_selected.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_selected.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/1_loop_selected.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_2.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_2.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_2.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_2.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_double_expanded_continuation.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_double_expanded_continuation.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_double_expanded_continuation.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_double_expanded_continuation.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0_teleporting.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0_teleporting.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0_teleporting.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_0_teleporting.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1_teleporting.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1_teleporting.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1_teleporting.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_select_1_teleporting.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_selected.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_selected.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_selected.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_equived_selected.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_with_equivs.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_with_equivs.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_with_equivs.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_edge_3_fractal_with_equivs.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation_selected.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation_selected.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation_selected.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_expanded_continuation_selected.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary_loops.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary_loops.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary_loops.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_horizontal_binary_loops.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_loop_2_select_1.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_loop_2_select_1.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_loop_2_select_1.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_loop_2_select_1.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_orange.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_orange.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_orange.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_orange.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_0.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_0.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_0.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_0.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_1.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_1.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_1.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_select_1.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_superposition.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_superposition.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_superposition.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_superposition.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_binary.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_binary.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_binary.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_binary.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_pink.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_pink.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_pink.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/2_vertical_pink.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/3.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/3.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_expanded_continuation.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_expanded_continuation.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/3_expanded_continuation.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_expanded_continuation.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_fractal.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_fractal.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/3_fractal.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_fractal.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_select_0.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_select_0.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/3_select_0.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_select_0.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_tertiary.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_tertiary.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/3_tertiary.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/3_tertiary.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_grid.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_grid.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_grid.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_grid.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_seperated.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_seperated.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_seperated.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_seperated.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_unordered.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_unordered.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_unordered.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/4_bits_unordered.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/branch.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/branch.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/branch.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/branch.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/branch_expanded.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/branch_expanded.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/branch_expanded.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/branch_expanded.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex_green.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex_green.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex_green.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/empty_vertex_green.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/header.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/header.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/header.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/header.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/naked_point.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/naked_point.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/naked_point.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/naked_point.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/some_structure.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/some_structure.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/some_structure.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/some_structure.png diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/1920x1080.jpeg b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/1920x1080.jpeg similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/1920x1080.jpeg rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/1920x1080.jpeg diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/3840x2160.jpeg b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/3840x2160.jpeg similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/3840x2160.jpeg rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/thumbnail/3840x2160.jpeg diff --git a/public/papers/on-orbits-equivalence-and-inconsistencies/images/two_vertices.png b/orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/two_vertices.png similarity index 100% rename from public/papers/on-orbits-equivalence-and-inconsistencies/images/two_vertices.png rename to orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/two_vertices.png diff --git a/public/papers/sitemap.xml b/orbitmines.com/public/papers/sitemap.xml similarity index 100% rename from public/papers/sitemap.xml rename to orbitmines.com/public/papers/sitemap.xml diff --git a/public/profiles/fadi-shawki.jpeg b/orbitmines.com/public/profiles/fadi-shawki.jpeg similarity index 100% rename from public/profiles/fadi-shawki.jpeg rename to orbitmines.com/public/profiles/fadi-shawki.jpeg diff --git a/public/profiles/fadi-shawki.pdf b/orbitmines.com/public/profiles/fadi-shawki.pdf similarity index 100% rename from public/profiles/fadi-shawki.pdf rename to orbitmines.com/public/profiles/fadi-shawki.pdf diff --git a/public/profiles/fadi-shawki/profile-picture.jpg b/orbitmines.com/public/profiles/fadi-shawki/profile-picture.jpg similarity index 100% rename from public/profiles/fadi-shawki/profile-picture.jpg rename to orbitmines.com/public/profiles/fadi-shawki/profile-picture.jpg diff --git a/public/profiles/sitemap.xml b/orbitmines.com/public/profiles/sitemap.xml similarity index 100% rename from public/profiles/sitemap.xml rename to orbitmines.com/public/profiles/sitemap.xml diff --git a/public/robots.txt b/orbitmines.com/public/robots.txt similarity index 100% rename from public/robots.txt rename to orbitmines.com/public/robots.txt diff --git a/public/sitemap.xml b/orbitmines.com/public/sitemap.xml similarity index 100% rename from public/sitemap.xml rename to orbitmines.com/public/sitemap.xml diff --git a/src/@orbitmines/explorer/JS.spec.ts b/orbitmines.com/src/@orbitmines/explorer/JS.spec.ts similarity index 100% rename from src/@orbitmines/explorer/JS.spec.ts rename to orbitmines.com/src/@orbitmines/explorer/JS.spec.ts diff --git a/src/@orbitmines/explorer/JS.ts b/orbitmines.com/src/@orbitmines/explorer/JS.ts similarity index 100% rename from src/@orbitmines/explorer/JS.ts rename to orbitmines.com/src/@orbitmines/explorer/JS.ts diff --git a/src/@orbitmines/explorer/JS2.ts b/orbitmines.com/src/@orbitmines/explorer/JS2.ts similarity index 100% rename from src/@orbitmines/explorer/JS2.ts rename to orbitmines.com/src/@orbitmines/explorer/JS2.ts diff --git a/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/orbitmines.com/src/@orbitmines/explorer/OrbitMinesExplorer.tsx similarity index 100% rename from src/@orbitmines/explorer/OrbitMinesExplorer.tsx rename to orbitmines.com/src/@orbitmines/explorer/OrbitMinesExplorer.tsx diff --git a/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md b/orbitmines.com/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md similarity index 100% rename from src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md rename to orbitmines.com/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md diff --git a/src/@orbitmines/explorer/REFACTOR_RENDER.md b/orbitmines.com/src/@orbitmines/explorer/REFACTOR_RENDER.md similarity index 100% rename from src/@orbitmines/explorer/REFACTOR_RENDER.md rename to orbitmines.com/src/@orbitmines/explorer/REFACTOR_RENDER.md diff --git a/src/@orbitmines/explorer/Ray.spec.ts b/orbitmines.com/src/@orbitmines/explorer/Ray.spec.ts similarity index 100% rename from src/@orbitmines/explorer/Ray.spec.ts rename to orbitmines.com/src/@orbitmines/explorer/Ray.spec.ts diff --git a/src/@orbitmines/explorer/Ray.ts b/orbitmines.com/src/@orbitmines/explorer/Ray.ts similarity index 100% rename from src/@orbitmines/explorer/Ray.ts rename to orbitmines.com/src/@orbitmines/explorer/Ray.ts diff --git a/src/@orbitmines/explorer/Ray2.ts b/orbitmines.com/src/@orbitmines/explorer/Ray2.ts similarity index 100% rename from src/@orbitmines/explorer/Ray2.ts rename to orbitmines.com/src/@orbitmines/explorer/Ray2.ts diff --git a/src/@orbitmines/explorer/Visualization.tsx b/orbitmines.com/src/@orbitmines/explorer/Visualization.tsx similarity index 100% rename from src/@orbitmines/explorer/Visualization.tsx rename to orbitmines.com/src/@orbitmines/explorer/Visualization.tsx diff --git a/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/orbitmines.com/src/@orbitmines/explorer/debug/DebugCanvas.tsx similarity index 100% rename from src/@orbitmines/explorer/debug/DebugCanvas.tsx rename to orbitmines.com/src/@orbitmines/explorer/debug/DebugCanvas.tsx diff --git a/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx b/orbitmines.com/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx similarity index 100% rename from src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx rename to orbitmines.com/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx diff --git a/src/@orbitmines/explorer/errors/errors.ts b/orbitmines.com/src/@orbitmines/explorer/errors/errors.ts similarity index 100% rename from src/@orbitmines/explorer/errors/errors.ts rename to orbitmines.com/src/@orbitmines/explorer/errors/errors.ts diff --git a/src/@orbitmines/external/chyp/Chyp.spec.ts b/orbitmines.com/src/@orbitmines/external/chyp/Chyp.spec.ts similarity index 100% rename from src/@orbitmines/external/chyp/Chyp.spec.ts rename to orbitmines.com/src/@orbitmines/external/chyp/Chyp.spec.ts diff --git a/src/@orbitmines/external/chyp/Chyp.ts b/orbitmines.com/src/@orbitmines/external/chyp/Chyp.ts similarity index 100% rename from src/@orbitmines/external/chyp/Chyp.ts rename to orbitmines.com/src/@orbitmines/external/chyp/Chyp.ts diff --git a/src/@orbitmines/external/chyp/ChypCanvas.tsx b/orbitmines.com/src/@orbitmines/external/chyp/ChypCanvas.tsx similarity index 100% rename from src/@orbitmines/external/chyp/ChypCanvas.tsx rename to orbitmines.com/src/@orbitmines/external/chyp/ChypCanvas.tsx diff --git a/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/orbitmines.com/src/@orbitmines/external/chyp/Chyp_naive_pass.ts similarity index 100% rename from src/@orbitmines/external/chyp/Chyp_naive_pass.ts rename to orbitmines.com/src/@orbitmines/external/chyp/Chyp_naive_pass.ts diff --git a/src/@orbitmines/external/chyp/README.md b/orbitmines.com/src/@orbitmines/external/chyp/README.md similarity index 100% rename from src/@orbitmines/external/chyp/README.md rename to orbitmines.com/src/@orbitmines/external/chyp/README.md diff --git a/src/@orbitmines/external/chyp/examples.ts b/orbitmines.com/src/@orbitmines/external/chyp/examples.ts similarity index 100% rename from src/@orbitmines/external/chyp/examples.ts rename to orbitmines.com/src/@orbitmines/external/chyp/examples.ts diff --git a/src/@orbitmines/js/react/IEventListener.tsx b/orbitmines.com/src/@orbitmines/js/react/IEventListener.tsx similarity index 100% rename from src/@orbitmines/js/react/IEventListener.tsx rename to orbitmines.com/src/@orbitmines/js/react/IEventListener.tsx diff --git a/src/@orbitmines/js/react/IModule.ts b/orbitmines.com/src/@orbitmines/js/react/IModule.ts similarity index 100% rename from src/@orbitmines/js/react/IModule.ts rename to orbitmines.com/src/@orbitmines/js/react/IModule.ts diff --git a/src/@orbitmines/js/react/Modules.tsx b/orbitmines.com/src/@orbitmines/js/react/Modules.tsx similarity index 100% rename from src/@orbitmines/js/react/Modules.tsx rename to orbitmines.com/src/@orbitmines/js/react/Modules.tsx diff --git a/src/@orbitmines/js/react/hooks/useHotkeys.ts b/orbitmines.com/src/@orbitmines/js/react/hooks/useHotkeys.ts similarity index 100% rename from src/@orbitmines/js/react/hooks/useHotkeys.ts rename to orbitmines.com/src/@orbitmines/js/react/hooks/useHotkeys.ts diff --git a/src/@orbitmines/js/react/hooks/useHovering.ts b/orbitmines.com/src/@orbitmines/js/react/hooks/useHovering.ts similarity index 100% rename from src/@orbitmines/js/react/hooks/useHovering.ts rename to orbitmines.com/src/@orbitmines/js/react/hooks/useHovering.ts diff --git a/src/@orbitmines/rays/index.ts b/orbitmines.com/src/@orbitmines/rays/index.ts similarity index 100% rename from src/@orbitmines/rays/index.ts rename to orbitmines.com/src/@orbitmines/rays/index.ts diff --git a/src/App.tsx b/orbitmines.com/src/App.tsx similarity index 100% rename from src/App.tsx rename to orbitmines.com/src/App.tsx diff --git a/src/index.tsx b/orbitmines.com/src/index.tsx similarity index 100% rename from src/index.tsx rename to orbitmines.com/src/index.tsx diff --git a/src/lib/index.ts b/orbitmines.com/src/lib/index.ts similarity index 100% rename from src/lib/index.ts rename to orbitmines.com/src/lib/index.ts diff --git a/src/lib/layout/experimental-designs/BlueprintJS.tsx b/orbitmines.com/src/lib/layout/experimental-designs/BlueprintJS.tsx similarity index 100% rename from src/lib/layout/experimental-designs/BlueprintJS.tsx rename to orbitmines.com/src/lib/layout/experimental-designs/BlueprintJS.tsx diff --git a/src/lib/layout/experimental-designs/Icons.tsx b/orbitmines.com/src/lib/layout/experimental-designs/Icons.tsx similarity index 100% rename from src/lib/layout/experimental-designs/Icons.tsx rename to orbitmines.com/src/lib/layout/experimental-designs/Icons.tsx diff --git a/src/lib/layout/experimental-designs/Legacy.tsx b/orbitmines.com/src/lib/layout/experimental-designs/Legacy.tsx similarity index 100% rename from src/lib/layout/experimental-designs/Legacy.tsx rename to orbitmines.com/src/lib/layout/experimental-designs/Legacy.tsx diff --git a/src/lib/layout/flexbox/Col.tsx b/orbitmines.com/src/lib/layout/flexbox/Col.tsx similarity index 100% rename from src/lib/layout/flexbox/Col.tsx rename to orbitmines.com/src/lib/layout/flexbox/Col.tsx diff --git a/src/lib/layout/flexbox/Grid.tsx b/orbitmines.com/src/lib/layout/flexbox/Grid.tsx similarity index 100% rename from src/lib/layout/flexbox/Grid.tsx rename to orbitmines.com/src/lib/layout/flexbox/Grid.tsx diff --git a/src/lib/layout/flexbox/Row.tsx b/orbitmines.com/src/lib/layout/flexbox/Row.tsx similarity index 100% rename from src/lib/layout/flexbox/Row.tsx rename to orbitmines.com/src/lib/layout/flexbox/Row.tsx diff --git a/src/lib/layout/flexbox/constants.ts b/orbitmines.com/src/lib/layout/flexbox/constants.ts similarity index 100% rename from src/lib/layout/flexbox/constants.ts rename to orbitmines.com/src/lib/layout/flexbox/constants.ts diff --git a/src/lib/layout/flexbox/index.ts b/orbitmines.com/src/lib/layout/flexbox/index.ts similarity index 100% rename from src/lib/layout/flexbox/index.ts rename to orbitmines.com/src/lib/layout/flexbox/index.ts diff --git a/src/lib/layout/flexbox/styles/flexbox.scss b/orbitmines.com/src/lib/layout/flexbox/styles/flexbox.scss similarity index 100% rename from src/lib/layout/flexbox/styles/flexbox.scss rename to orbitmines.com/src/lib/layout/flexbox/styles/flexbox.scss diff --git a/src/lib/layout/font/Font.tsx b/orbitmines.com/src/lib/layout/font/Font.tsx similarity index 100% rename from src/lib/layout/font/Font.tsx rename to orbitmines.com/src/lib/layout/font/Font.tsx diff --git a/src/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono-2.242.zip b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono-2.242.zip similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono-2.242.zip rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono-2.242.zip diff --git a/src/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono.ts b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono.ts similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono.ts rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/JetBrainsMono.ts diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Italic.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Italic.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Italic.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Italic.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Regular.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Regular.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Regular.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL SemiBold_Regular.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Italic.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Italic.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Italic.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Italic.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Regular.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Regular.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Regular.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL Thin_Regular.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL_Regular.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL_Regular.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL_Regular.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono NL_Regular.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Italic.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Italic.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Italic.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Italic.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Regular.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Regular.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Regular.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono SemiBold_Regular.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Italic.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Italic.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Italic.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Italic.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Regular.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Regular.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Regular.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono Thin_Regular.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono_Regular.json b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono_Regular.json similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono_Regular.json rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/json/JetBrains Mono_Regular.json diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Bold.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Bold.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Bold.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Bold.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-BoldItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-BoldItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-BoldItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-BoldItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBold.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBold.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBold.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBold.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBoldItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBoldItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBoldItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraBoldItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLight.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLight.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLight.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLight.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLightItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLightItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLightItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ExtraLightItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Italic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Italic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Italic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Italic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Light.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Light.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Light.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Light.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-LightItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-LightItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-LightItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-LightItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Medium.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Medium.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Medium.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Medium.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-MediumItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-MediumItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-MediumItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-MediumItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Regular.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Regular.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Regular.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Regular.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBold.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBold.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBold.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBold.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBoldItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBoldItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBoldItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-SemiBoldItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Thin.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Thin.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Thin.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-Thin.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ThinItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ThinItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ThinItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMono-ThinItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Bold.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Bold.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Bold.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Bold.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-BoldItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-BoldItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-BoldItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-BoldItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBold.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBold.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBold.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBold.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBoldItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBoldItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBoldItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraBoldItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLight.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLight.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLight.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLight.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLightItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLightItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLightItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ExtraLightItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Italic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Italic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Italic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Italic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Light.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Light.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Light.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Light.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-LightItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-LightItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-LightItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-LightItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Medium.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Medium.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Medium.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Medium.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-MediumItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-MediumItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-MediumItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-MediumItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Regular.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Regular.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Regular.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Regular.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBold.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBold.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBold.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBold.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBoldItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBoldItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBoldItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-SemiBoldItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Thin.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Thin.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Thin.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-Thin.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ThinItalic.ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ThinItalic.ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ThinItalic.ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/ttf/JetBrainsMonoNL-ThinItalic.ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono-Italic[wght].ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono-Italic[wght].ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono-Italic[wght].ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono-Italic[wght].ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono[wght].ttf b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono[wght].ttf similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono[wght].ttf rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/variable/JetBrainsMono[wght].ttf diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Bold.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Bold.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Bold.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Bold.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-BoldItalic.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-BoldItalic.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-BoldItalic.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-BoldItalic.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBold.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBold.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBold.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBold.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBoldItalic.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBoldItalic.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBoldItalic.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraBoldItalic.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLight.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLight.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLight.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLight.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLightItalic.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLightItalic.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLightItalic.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ExtraLightItalic.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Italic.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Italic.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Italic.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Italic.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Light.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Light.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Light.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Light.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-LightItalic.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-LightItalic.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-LightItalic.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-LightItalic.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Medium.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Medium.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Medium.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Medium.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-MediumItalic.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-MediumItalic.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-MediumItalic.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-MediumItalic.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Regular.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Regular.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Regular.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Regular.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBold.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBold.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBold.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBold.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBoldItalic.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBoldItalic.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBoldItalic.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-SemiBoldItalic.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Thin.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Thin.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Thin.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-Thin.woff2 diff --git a/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ThinItalic.woff2 b/orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ThinItalic.woff2 similarity index 100% rename from src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ThinItalic.woff2 rename to orbitmines.com/src/lib/layout/font/fonts/JetBrainsMono/webfonts/JetBrainsMono-ThinItalic.woff2 diff --git a/src/lib/layout/font/styles/font.scss b/orbitmines.com/src/lib/layout/font/styles/font.scss similarity index 100% rename from src/lib/layout/font/styles/font.scss rename to orbitmines.com/src/lib/layout/font/styles/font.scss diff --git a/src/lib/layout/icons/CustomIcon.tsx b/orbitmines.com/src/lib/layout/icons/CustomIcon.tsx similarity index 100% rename from src/lib/layout/icons/CustomIcon.tsx rename to orbitmines.com/src/lib/layout/icons/CustomIcon.tsx diff --git a/src/lib/layout/styles/blueprintjs/styles/blueprintjs.scss b/orbitmines.com/src/lib/layout/styles/blueprintjs/styles/blueprintjs.scss similarity index 100% rename from src/lib/layout/styles/blueprintjs/styles/blueprintjs.scss rename to orbitmines.com/src/lib/layout/styles/blueprintjs/styles/blueprintjs.scss diff --git a/src/lib/layout/styles/index.scss b/orbitmines.com/src/lib/layout/styles/index.scss similarity index 100% rename from src/lib/layout/styles/index.scss rename to orbitmines.com/src/lib/layout/styles/index.scss diff --git a/src/lib/layout/styles/spacing.scss b/orbitmines.com/src/lib/layout/styles/spacing.scss similarity index 100% rename from src/lib/layout/styles/spacing.scss rename to orbitmines.com/src/lib/layout/styles/spacing.scss diff --git a/src/lib/organizations/3b1b/3B1B_Logo.svg.png b/orbitmines.com/src/lib/organizations/3b1b/3B1B_Logo.svg.png similarity index 100% rename from src/lib/organizations/3b1b/3B1B_Logo.svg.png rename to orbitmines.com/src/lib/organizations/3b1b/3B1B_Logo.svg.png diff --git a/src/lib/organizations/ORGANIZATIONS.ts b/orbitmines.com/src/lib/organizations/ORGANIZATIONS.ts similarity index 100% rename from src/lib/organizations/ORGANIZATIONS.ts rename to orbitmines.com/src/lib/organizations/ORGANIZATIONS.ts diff --git a/src/lib/organizations/README.md b/orbitmines.com/src/lib/organizations/README.md similarity index 100% rename from src/lib/organizations/README.md rename to orbitmines.com/src/lib/organizations/README.md diff --git a/src/lib/organizations/akissinger/881183.png b/orbitmines.com/src/lib/organizations/akissinger/881183.png similarity index 100% rename from src/lib/organizations/akissinger/881183.png rename to orbitmines.com/src/lib/organizations/akissinger/881183.png diff --git a/src/lib/organizations/critical-thinking/he8VyFCv_400x400.jpg b/orbitmines.com/src/lib/organizations/critical-thinking/he8VyFCv_400x400.jpg similarity index 100% rename from src/lib/organizations/critical-thinking/he8VyFCv_400x400.jpg rename to orbitmines.com/src/lib/organizations/critical-thinking/he8VyFCv_400x400.jpg diff --git a/src/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.avif b/orbitmines.com/src/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.avif similarity index 100% rename from src/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.avif rename to orbitmines.com/src/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.avif diff --git a/src/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.png b/orbitmines.com/src/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.png similarity index 100% rename from src/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.png rename to orbitmines.com/src/lib/organizations/critical-thinking/https___s3.us-west-1.amazonaws.com_redwood-labs_showpage_uploads_images_403b35d6-ec76-4cd9-a70d-bd1c5d825460.png diff --git a/src/lib/organizations/discord/discord-mark-white.svg b/orbitmines.com/src/lib/organizations/discord/discord-mark-white.svg similarity index 100% rename from src/lib/organizations/discord/discord-mark-white.svg rename to orbitmines.com/src/lib/organizations/discord/discord-mark-white.svg diff --git a/src/lib/organizations/fission.codes/d399fc1f178d48c7b9f775ed1f6b9a4ff5f851c2.svg b/orbitmines.com/src/lib/organizations/fission.codes/d399fc1f178d48c7b9f775ed1f6b9a4ff5f851c2.svg similarity index 100% rename from src/lib/organizations/fission.codes/d399fc1f178d48c7b9f775ed1f6b9a4ff5f851c2.svg rename to orbitmines.com/src/lib/organizations/fission.codes/d399fc1f178d48c7b9f775ed1f6b9a4ff5f851c2.svg diff --git a/src/lib/organizations/github/GitHub-Logos.zip b/orbitmines.com/src/lib/organizations/github/GitHub-Logos.zip similarity index 100% rename from src/lib/organizations/github/GitHub-Logos.zip rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos.zip diff --git a/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.ai b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.ai similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.ai rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.ai diff --git a/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.eps b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.eps similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.eps rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.eps diff --git a/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.png b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.png similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.png rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.png diff --git a/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.psd b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.psd similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.psd rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo.psd diff --git a/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.png b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.png similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.png rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.png diff --git a/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.psd b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.psd similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.psd rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/GitHub_Logo_White.psd diff --git a/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/README.txt b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/README.txt similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/GitHub-Logos/README.txt rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/GitHub-Logos/README.txt diff --git a/src/lib/organizations/github/GitHub-Logos/__MACOSX/._GitHub-Logos b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/._GitHub-Logos similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/__MACOSX/._GitHub-Logos rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/._GitHub-Logos diff --git a/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.ai b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.ai similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.ai rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.ai diff --git a/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.eps b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.eps similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.eps rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.eps diff --git a/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.png b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.png similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.png rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.png diff --git a/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.psd b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.psd similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.psd rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo.psd diff --git a/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.png b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.png similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.png rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.png diff --git a/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.psd b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.psd similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.psd rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._GitHub_Logo_White.psd diff --git a/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._README.txt b/orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._README.txt similarity index 100% rename from src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._README.txt rename to orbitmines.com/src/lib/organizations/github/GitHub-Logos/__MACOSX/GitHub-Logos/._README.txt diff --git a/src/lib/organizations/github/github-mark.zip b/orbitmines.com/src/lib/organizations/github/github-mark.zip similarity index 100% rename from src/lib/organizations/github/github-mark.zip rename to orbitmines.com/src/lib/organizations/github/github-mark.zip diff --git a/src/lib/organizations/github/github-mark/__MACOSX/._github-mark b/orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/._github-mark similarity index 100% rename from src/lib/organizations/github/github-mark/__MACOSX/._github-mark rename to orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/._github-mark diff --git a/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.png b/orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.png similarity index 100% rename from src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.png rename to orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.png diff --git a/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.svg b/orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.svg similarity index 100% rename from src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.svg rename to orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark-white.svg diff --git a/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.png b/orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.png similarity index 100% rename from src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.png rename to orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.png diff --git a/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.svg b/orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.svg similarity index 100% rename from src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.svg rename to orbitmines.com/src/lib/organizations/github/github-mark/__MACOSX/github-mark/._github-mark.svg diff --git a/src/lib/organizations/github/github-mark/github-mark/github-mark-white.png b/orbitmines.com/src/lib/organizations/github/github-mark/github-mark/github-mark-white.png similarity index 100% rename from src/lib/organizations/github/github-mark/github-mark/github-mark-white.png rename to orbitmines.com/src/lib/organizations/github/github-mark/github-mark/github-mark-white.png diff --git a/src/lib/organizations/github/github-mark/github-mark/github-mark-white.svg b/orbitmines.com/src/lib/organizations/github/github-mark/github-mark/github-mark-white.svg similarity index 100% rename from src/lib/organizations/github/github-mark/github-mark/github-mark-white.svg rename to orbitmines.com/src/lib/organizations/github/github-mark/github-mark/github-mark-white.svg diff --git a/src/lib/organizations/github/github-mark/github-mark/github-mark.png b/orbitmines.com/src/lib/organizations/github/github-mark/github-mark/github-mark.png similarity index 100% rename from src/lib/organizations/github/github-mark/github-mark/github-mark.png rename to orbitmines.com/src/lib/organizations/github/github-mark/github-mark/github-mark.png diff --git a/src/lib/organizations/github/github-mark/github-mark/github-mark.svg b/orbitmines.com/src/lib/organizations/github/github-mark/github-mark/github-mark.svg similarity index 100% rename from src/lib/organizations/github/github-mark/github-mark/github-mark.svg rename to orbitmines.com/src/lib/organizations/github/github-mark/github-mark/github-mark.svg diff --git a/src/lib/organizations/gitlab.com/gitlab-logo-700.svg b/orbitmines.com/src/lib/organizations/gitlab.com/gitlab-logo-700.svg similarity index 100% rename from src/lib/organizations/gitlab.com/gitlab-logo-700.svg rename to orbitmines.com/src/lib/organizations/gitlab.com/gitlab-logo-700.svg diff --git a/src/lib/organizations/hoc/92327702.png b/orbitmines.com/src/lib/organizations/hoc/92327702.png similarity index 100% rename from src/lib/organizations/hoc/92327702.png rename to orbitmines.com/src/lib/organizations/hoc/92327702.png diff --git a/src/lib/organizations/hoc/Favicon.png b/orbitmines.com/src/lib/organizations/hoc/Favicon.png similarity index 100% rename from src/lib/organizations/hoc/Favicon.png rename to orbitmines.com/src/lib/organizations/hoc/Favicon.png diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022.zip b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022.zip similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022.zip rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022.zip diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.jpg b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.jpg similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.jpg rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.jpg diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.png b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.png similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.png rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient copy.png diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.ai b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.ai similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.ai rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.ai diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.jpg b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.jpg similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.jpg rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.jpg diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.png b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.png similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.png rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient.png diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient_RGB.svg b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient_RGB.svg similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient_RGB.svg rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/01 Gradient Glyph/Instagram_Glyph_Gradient_RGB.svg diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.ai b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.ai similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.ai rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.ai diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.png b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.png similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.png rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.png diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.svg b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.svg similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.svg rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/02 White Glyph/Instagram_Glyph_White.svg diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.ai b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.ai similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.ai rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.ai diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.jpg b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.jpg similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.jpg rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.jpg diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.png b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.png similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.png rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.png diff --git a/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.svg b/orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.svg similarity index 100% rename from src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.svg rename to orbitmines.com/src/lib/organizations/instagram/IG_brand_asset_pack_2022/Instagram Logo Pack/03 Black Glyph/Instagram_Glyph_Black.svg diff --git a/src/lib/organizations/ipfs/ipfs.svg b/orbitmines.com/src/lib/organizations/ipfs/ipfs.svg similarity index 100% rename from src/lib/organizations/ipfs/ipfs.svg rename to orbitmines.com/src/lib/organizations/ipfs/ipfs.svg diff --git a/src/lib/organizations/joinmastodon.org/logo-black.svg b/orbitmines.com/src/lib/organizations/joinmastodon.org/logo-black.svg similarity index 100% rename from src/lib/organizations/joinmastodon.org/logo-black.svg rename to orbitmines.com/src/lib/organizations/joinmastodon.org/logo-black.svg diff --git a/src/lib/organizations/joinmastodon.org/logo-purple.png b/orbitmines.com/src/lib/organizations/joinmastodon.org/logo-purple.png similarity index 100% rename from src/lib/organizations/joinmastodon.org/logo-purple.png rename to orbitmines.com/src/lib/organizations/joinmastodon.org/logo-purple.png diff --git a/src/lib/organizations/joinmastodon.org/logo-purple.svg b/orbitmines.com/src/lib/organizations/joinmastodon.org/logo-purple.svg similarity index 100% rename from src/lib/organizations/joinmastodon.org/logo-purple.svg rename to orbitmines.com/src/lib/organizations/joinmastodon.org/logo-purple.svg diff --git a/src/lib/organizations/lexfridman-podcast/download.jpeg b/orbitmines.com/src/lib/organizations/lexfridman-podcast/download.jpeg similarity index 100% rename from src/lib/organizations/lexfridman-podcast/download.jpeg rename to orbitmines.com/src/lib/organizations/lexfridman-podcast/download.jpeg diff --git a/src/lib/organizations/linkedin/LinkedIn-Logos.zip b/orbitmines.com/src/lib/organizations/linkedin/LinkedIn-Logos.zip similarity index 100% rename from src/lib/organizations/linkedin/LinkedIn-Logos.zip rename to orbitmines.com/src/lib/organizations/linkedin/LinkedIn-Logos.zip diff --git a/src/lib/organizations/linkedin/LinkedIn-Logos/LI-In-Bug.png b/orbitmines.com/src/lib/organizations/linkedin/LinkedIn-Logos/LI-In-Bug.png similarity index 100% rename from src/lib/organizations/linkedin/LinkedIn-Logos/LI-In-Bug.png rename to orbitmines.com/src/lib/organizations/linkedin/LinkedIn-Logos/LI-In-Bug.png diff --git a/src/lib/organizations/linkedin/LinkedIn-Logos/LI-Logo.png b/orbitmines.com/src/lib/organizations/linkedin/LinkedIn-Logos/LI-Logo.png similarity index 100% rename from src/lib/organizations/linkedin/LinkedIn-Logos/LI-Logo.png rename to orbitmines.com/src/lib/organizations/linkedin/LinkedIn-Logos/LI-Logo.png diff --git a/src/lib/organizations/linkedin/linkedin-logos.zip b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos.zip similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos.zip rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos.zip diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-128.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-14.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-21.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-26.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-34.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-40.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-48.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-72.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/1x/In-Blue-96.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-128@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-14@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-21@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-26@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-34@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-40@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-48@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-72@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/Blue/2x/In-Blue-96@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-128.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-14.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-21.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-26.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-34.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-40.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-48.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-72.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/1x/In-White-96.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-128@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-14@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-21@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-26@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-34@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-40@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-48@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-72@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Digital/White/2x/In-White-96@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/Blue/In-CMYK-Blue-S.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/CMYK/White/In-CMYK-White-S.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/In/Print/PMS/In-PMS2174U-S.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-128@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-14@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-21@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-26@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-34@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-40@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-48-\342\224\254\302\253@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-72-\342\224\254\302\253@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Digital/Blue/2x/LinkedIn-Blue-96@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/Blue/LinkedIn-CMYK-Blue-S.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/CMYK/White/LinkedIn-CMYK-White-S.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/LinkedIn-Logos/Logo/Print/PMS/LinkedIn-PMS2174U-S.eps diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/._LinkedIn-Logos b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/._LinkedIn-Logos similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/._LinkedIn-Logos rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/._LinkedIn-Logos diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._In b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._In similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._In rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._In diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._Logo b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._Logo similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._Logo rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/._Logo diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Digital b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Digital similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Digital rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Digital diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Print b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Print similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Print rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/._Print diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._Blue b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._Blue similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._Blue rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._Blue diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._White b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._White similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._White rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/._White diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._1x b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._1x similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._1x rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._1x diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._2x b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._2x similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._2x rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/._2x diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-128.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-14.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-21.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-26.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-34.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-40.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-48.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-72.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/1x/._In-Blue-96.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-128@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-14@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-21@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-26@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-34@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-40@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-48@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-72@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/Blue/2x/._In-Blue-96@2x.png diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._1x b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._1x similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._1x rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._1x diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._2x b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._2x similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._2x rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/._2x diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-128.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-14.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-21.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-26.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-34.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-40.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-48.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-72.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\316\223\303\244\303\263.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\316\223\303\244\303\263.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\316\223\303\244\303\263.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\316\223\303\244\303\263.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\342\224\254\302\253.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\342\224\254\302\253.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\342\224\254\302\253.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96-\342\224\254\302\253.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/1x/._In-White-96.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-128@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-14@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-21@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-26@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-34@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-40@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-48@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-72@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Digital/White/2x/._In-White-96@2x.png diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._CMYK b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._CMYK similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._CMYK rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._CMYK diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._PMS b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._PMS similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._PMS rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/._PMS diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._Blue b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._Blue similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._Blue rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._Blue diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._White b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._White similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._White rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/._White diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/Blue/._In-CMYK-Blue-S.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/CMYK/White/._In-CMYK-White-S.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/In/Print/PMS/._In-PMS2174U-S.eps diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Digital b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Digital similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Digital rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Digital diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Print b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Print similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Print rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/._Print diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/._Blue b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/._Blue similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/._Blue rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/._Blue diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/._2x b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/._2x similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/._2x rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/._2x diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\316\223\303\244\303\263@2x.png_Error.txt" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-128@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-14@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-21@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-26@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-34@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40-\342\224\254\302\253@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-40@2x.png diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-48-\342\224\254\302\253@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\316\223\303\244\303\263@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\342\224\254\302\253@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\342\224\254\302\253@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\342\224\254\302\253@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-72-\342\224\254\302\253@2x.png" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96-\316\223\303\244\303\263@2x.png" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96@2x.png b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96@2x.png similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96@2x.png rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Digital/Blue/2x/._LinkedIn-Blue-96@2x.png diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._CMYK b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._CMYK similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._CMYK rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._CMYK diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._PMS b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._PMS similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._PMS rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/._PMS diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._Blue b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._Blue similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._Blue rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._Blue diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._White b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._White similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._White rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/._White diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/Blue/._LinkedIn-CMYK-Blue-S.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/CMYK/White/._LinkedIn-CMYK-White-S.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-L.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M-\316\223\303\244\303\263.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-M.eps diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\316\223\303\244\303\263.eps" diff --git "a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" "b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" similarity index 100% rename from "src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" rename to "orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S-\342\224\254\302\253.eps" diff --git a/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S.eps b/orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S.eps similarity index 100% rename from src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S.eps rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-logos/__MACOSX/LinkedIn-Logos/Logo/Print/PMS/._LinkedIn-PMS2174U-S.eps diff --git a/src/lib/organizations/linkedin/linkedin-svgrepo-com.svg b/orbitmines.com/src/lib/organizations/linkedin/linkedin-svgrepo-com.svg similarity index 100% rename from src/lib/organizations/linkedin/linkedin-svgrepo-com.svg rename to orbitmines.com/src/lib/organizations/linkedin/linkedin-svgrepo-com.svg diff --git a/src/lib/organizations/meta/Facebook-Brand-Asset-Pack.zip b/orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack.zip similarity index 100% rename from src/lib/organizations/meta/Facebook-Brand-Asset-Pack.zip rename to orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack.zip diff --git a/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.ai b/orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.ai similarity index 100% rename from src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.ai rename to orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.ai diff --git a/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.png b/orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.png similarity index 100% rename from src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.png rename to orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Primary Logo/Facebook_Logo_Primary.png diff --git a/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.ai b/orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.ai similarity index 100% rename from src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.ai rename to orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.ai diff --git a/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.png b/orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.png similarity index 100% rename from src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.png rename to orbitmines.com/src/lib/organizations/meta/Facebook-Brand-Asset-Pack/Facebook Brand Asset Pack/Logo/Secondary Logo/Facebook_Logo_Secondary.png diff --git a/src/lib/organizations/meta/Meta_Company-Lockup.zip b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup.zip similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup.zip rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup.zip diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.ai b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.ai similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.ai rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.ai diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.jpg b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.jpg similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.jpg rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.jpg diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.png b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.png similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.png rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.png diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.svg b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.svg similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.svg rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/1 Positive Primary/RGB/Meta_lockup_positive primary_RGB.svg diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.ai b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.ai similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.ai rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.ai diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.png b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.png similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.png rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.png diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.svg b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.svg similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.svg rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/2 Negative Primary/RGB/Meta_lockup_negative primary_white_RGB.svg diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.ai b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.ai similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.ai rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.ai diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.png b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.png similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.png rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.png diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.svg b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.svg similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.svg rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/3 Mono Black/RGB/Meta_lockup_mono_black_RGB.svg diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.ai b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.ai similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.ai rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.ai diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.png b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.png similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.png rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.png diff --git a/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.svg b/orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.svg similarity index 100% rename from src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.svg rename to orbitmines.com/src/lib/organizations/meta/Meta_Company-Lockup/Meta_Company Lockup/4 Mono White/RGB/Meta_lockup_mono_white_RGB.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center.zip b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center.zip similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center.zip rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center.zip diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Black/Digital_Glyph_Black.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Black/Digital_Glyph_Black.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Black/Digital_Glyph_Black.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Black/Digital_Glyph_Black.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Dark Green/Digital_Glyph_Dark_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Dark Green/Digital_Glyph_Dark_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Dark Green/Digital_Glyph_Dark_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Dark Green/Digital_Glyph_Dark_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Green/Digital_Glyph_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Green/Digital_Glyph_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Green/Digital_Glyph_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/Green/Digital_Glyph_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/White/Digital_Glyph_White.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/White/Digital_Glyph_White.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/White/Digital_Glyph_White.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/01_AI/White/Digital_Glyph_White.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Black/Digital_Glyph_Black.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Black/Digital_Glyph_Black.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Black/Digital_Glyph_Black.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Black/Digital_Glyph_Black.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Dark Green/Digital_Glyph_Dark_Green.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Dark Green/Digital_Glyph_Dark_Green.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Dark Green/Digital_Glyph_Dark_Green.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Dark Green/Digital_Glyph_Dark_Green.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Green/Digital_Glyph_Green.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Green/Digital_Glyph_Green.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Green/Digital_Glyph_Green.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/Green/Digital_Glyph_Green.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/White/Digital_Glyph_White.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/White/Digital_Glyph_White.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/White/Digital_Glyph_White.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/02_SVG/White/Digital_Glyph_White.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Black/Digital_Glyph_Black.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Black/Digital_Glyph_Black.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Black/Digital_Glyph_Black.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Black/Digital_Glyph_Black.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Dark Green/Digital_Glyph_Dark_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Dark Green/Digital_Glyph_Dark_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Dark Green/Digital_Glyph_Dark_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Dark Green/Digital_Glyph_Dark_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Green/Digital_Glyph_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Green/Digital_Glyph_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Green/Digital_Glyph_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/Green/Digital_Glyph_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/White/Digital_Glyph_White.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/White/Digital_Glyph_White.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/White/Digital_Glyph_White.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/01_Digital/03_PNG/White/Digital_Glyph_White.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Black/Print_Glyph_Black.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Black/Print_Glyph_Black.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Black/Print_Glyph_Black.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Black/Print_Glyph_Black.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Dark Green/Print_Glyph_Dark_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Dark Green/Print_Glyph_Dark_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Dark Green/Print_Glyph_Dark_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Dark Green/Print_Glyph_Dark_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Green/Print_Glyph_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Green/Print_Glyph_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Green/Print_Glyph_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/Green/Print_Glyph_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/White/Print_Glyph_White.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/White/Print_Glyph_White.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/White/Print_Glyph_White.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/01_AI/White/Print_Glyph_White.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Black/Print_Glyph_Black.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Black/Print_Glyph_Black.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Black/Print_Glyph_Black.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Black/Print_Glyph_Black.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Dark Green/Print_Glyph_Dark_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Dark Green/Print_Glyph_Dark_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Dark Green/Print_Glyph_Dark_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Dark Green/Print_Glyph_Dark_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Green/Print_Glyph_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Green/Print_Glyph_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Green/Print_Glyph_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/Green/Print_Glyph_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/White/Print_Glyph_White.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/White/Print_Glyph_White.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/White/Print_Glyph_White.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/01_Glyph/02_Print/03_PNG/White/Print_Glyph_White.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Black/Digital_Inline_Black.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Black/Digital_Inline_Black.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Black/Digital_Inline_Black.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Black/Digital_Inline_Black.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Dark Green/Digital_Inline_Dark_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Dark Green/Digital_Inline_Dark_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Dark Green/Digital_Inline_Dark_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Dark Green/Digital_Inline_Dark_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Green/Digital_Inline_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Green/Digital_Inline_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Green/Digital_Inline_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/Green/Digital_Inline_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/White/Digital_Inline_White.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/White/Digital_Inline_White.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/White/Digital_Inline_White.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/01_AI/White/Digital_Inline_White.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Black/Digital_Inline_Black.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Black/Digital_Inline_Black.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Black/Digital_Inline_Black.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Black/Digital_Inline_Black.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Dark Green/Digital_Inline_Dark_Green.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Dark Green/Digital_Inline_Dark_Green.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Dark Green/Digital_Inline_Dark_Green.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Dark Green/Digital_Inline_Dark_Green.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Green/Digital_Inline_Green.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Green/Digital_Inline_Green.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Green/Digital_Inline_Green.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/Green/Digital_Inline_Green.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/White/Digital_Inline_White.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/White/Digital_Inline_White.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/White/Digital_Inline_White.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/02_SVG/White/Digital_Inline_White.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Black/Digital_Inline_Black.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Black/Digital_Inline_Black.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Black/Digital_Inline_Black.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Black/Digital_Inline_Black.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Dark Green/Digital_Inline_Dark_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Dark Green/Digital_Inline_Dark_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Dark Green/Digital_Inline_Dark_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Dark Green/Digital_Inline_Dark_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Green/Digital_Inline_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Green/Digital_Inline_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Green/Digital_Inline_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/Green/Digital_Inline_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/White/Digital_Inline_White.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/White/Digital_Inline_White.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/White/Digital_Inline_White.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/01_Digital/03_PNG/White/Digital_Inline_White.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Black/Print_Inline_Black.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Black/Print_Inline_Black.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Black/Print_Inline_Black.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Black/Print_Inline_Black.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Dark Green/Print_Inline_Dark_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Dark Green/Print_Inline_Dark_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Dark Green/Print_Inline_Dark_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Dark Green/Print_Inline_Dark_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Green/Print_Inline_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Green/Print_Inline_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Green/Print_Inline_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/Green/Print_Inline_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/White/Print_Inline_White.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/White/Print_Inline_White.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/White/Print_Inline_White.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/01_AI/White/Print_Inline_White.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Black/Print_Inline_Black.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Black/Print_Inline_Black.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Black/Print_Inline_Black.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Black/Print_Inline_Black.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Dark Green/Print_Inline_Dark_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Dark Green/Print_Inline_Dark_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Dark Green/Print_Inline_Dark_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Dark Green/Print_Inline_Dark_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Green/Print_Inline_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Green/Print_Inline_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Green/Print_Inline_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/Green/Print_Inline_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/White/Print_Inline_White.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/White/Print_Inline_White.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/White/Print_Inline_White.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/02_Inline/02_Print/03_PNG/White/Print_Inline_White.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Black/Digital_Stacked_Black.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Black/Digital_Stacked_Black.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Black/Digital_Stacked_Black.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Black/Digital_Stacked_Black.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Dark Green/Digital_Stacked_Dark_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Dark Green/Digital_Stacked_Dark_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Dark Green/Digital_Stacked_Dark_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Dark Green/Digital_Stacked_Dark_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Green/Digital_Stacked_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Green/Digital_Stacked_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Green/Digital_Stacked_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/Green/Digital_Stacked_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/White/Digital_Stacked_White.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/White/Digital_Stacked_White.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/White/Digital_Stacked_White.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/01_AI/White/Digital_Stacked_White.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Black/Digital_Stacked_Black.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Black/Digital_Stacked_Black.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Black/Digital_Stacked_Black.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Black/Digital_Stacked_Black.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Dark Green/Digital_Stacked_Dark_Green.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Dark Green/Digital_Stacked_Dark_Green.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Dark Green/Digital_Stacked_Dark_Green.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Dark Green/Digital_Stacked_Dark_Green.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Green/Digital_Stacked_Green.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Green/Digital_Stacked_Green.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Green/Digital_Stacked_Green.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/Green/Digital_Stacked_Green.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/White/Digital_Stacked_White.svg b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/White/Digital_Stacked_White.svg similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/White/Digital_Stacked_White.svg rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/02_SVG/White/Digital_Stacked_White.svg diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Black/Digital_Stacked_Black.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Black/Digital_Stacked_Black.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Black/Digital_Stacked_Black.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Black/Digital_Stacked_Black.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Dark Green/Digital_Stacked_Dark_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Dark Green/Digital_Stacked_Dark_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Dark Green/Digital_Stacked_Dark_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Dark Green/Digital_Stacked_Dark_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Green/Digital_Stacked_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Green/Digital_Stacked_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Green/Digital_Stacked_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/Green/Digital_Stacked_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/White/Digital_Stacked_White.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/White/Digital_Stacked_White.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/White/Digital_Stacked_White.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/01_Digital/03_PNG/White/Digital_Stacked_White.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Black/Print_Stacked_Black.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Black/Print_Stacked_Black.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Black/Print_Stacked_Black.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Black/Print_Stacked_Black.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Dark Green/Print_Stacked_Dark_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Dark Green/Print_Stacked_Dark_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Dark Green/Print_Stacked_Dark_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Dark Green/Print_Stacked_Dark_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Green/Print_Stacked_Green.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Green/Print_Stacked_Green.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Green/Print_Stacked_Green.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/Green/Print_Stacked_Green.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/White/Print_Stacked_White.ai b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/White/Print_Stacked_White.ai similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/White/Print_Stacked_White.ai rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/01_AI/White/Print_Stacked_White.ai diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Black/Print_Stacked_Black.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Black/Print_Stacked_Black.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Black/Print_Stacked_Black.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Black/Print_Stacked_Black.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Dark Green/Print_Stacked_Dark_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Dark Green/Print_Stacked_Dark_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Dark Green/Print_Stacked_Dark_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Dark Green/Print_Stacked_Dark_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Green/Print_Stacked_Green.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Green/Print_Stacked_Green.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Green/Print_Stacked_Green.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/Green/Print_Stacked_Green.png diff --git a/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/White/Print_Stacked_White.png b/orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/White/Print_Stacked_White.png similarity index 100% rename from src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/White/Print_Stacked_White.png rename to orbitmines.com/src/lib/organizations/meta/WhatsApp-Brand-Resource-Center/03_Stacked/02_Print/03_PNG/White/Print_Stacked_White.png diff --git a/src/lib/organizations/mlst/channels4_profile.jpg b/orbitmines.com/src/lib/organizations/mlst/channels4_profile.jpg similarity index 100% rename from src/lib/organizations/mlst/channels4_profile.jpg rename to orbitmines.com/src/lib/organizations/mlst/channels4_profile.jpg diff --git a/src/lib/organizations/ngi/Logo-NGI_Icon-circle-NGI-rgb.png b/orbitmines.com/src/lib/organizations/ngi/Logo-NGI_Icon-circle-NGI-rgb.png similarity index 100% rename from src/lib/organizations/ngi/Logo-NGI_Icon-circle-NGI-rgb.png rename to orbitmines.com/src/lib/organizations/ngi/Logo-NGI_Icon-circle-NGI-rgb.png diff --git a/src/lib/organizations/nixos/nixos-icon.svg b/orbitmines.com/src/lib/organizations/nixos/nixos-icon.svg similarity index 100% rename from src/lib/organizations/nixos/nixos-icon.svg rename to orbitmines.com/src/lib/organizations/nixos/nixos-icon.svg diff --git a/src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.16x16.png b/orbitmines.com/src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.16x16.png similarity index 100% rename from src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.16x16.png rename to orbitmines.com/src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.16x16.png diff --git a/src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.64x64.png b/orbitmines.com/src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.64x64.png similarity index 100% rename from src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.64x64.png rename to orbitmines.com/src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.64x64.png diff --git a/src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.734x720.png b/orbitmines.com/src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.734x720.png similarity index 100% rename from src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.734x720.png rename to orbitmines.com/src/lib/organizations/orbitmines/icon/legacy/orbitmines.icon.legacy.734x720.png diff --git a/src/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.2.png b/orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.2.png similarity index 100% rename from src/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.2.png rename to orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.2.png diff --git a/src/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.png b/orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.png similarity index 100% rename from src/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.png rename to orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.550x550.png diff --git a/src/lib/organizations/orbitmines/icon/orbitmines.icon.64x64.png b/orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.64x64.png similarity index 100% rename from src/lib/organizations/orbitmines/icon/orbitmines.icon.64x64.png rename to orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.64x64.png diff --git a/src/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.min.png b/orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.min.png similarity index 100% rename from src/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.min.png rename to orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.min.png diff --git a/src/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.png b/orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.png similarity index 100% rename from src/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.png rename to orbitmines.com/src/lib/organizations/orbitmines/icon/orbitmines.icon.650x650.png diff --git a/src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.2000x419.png b/orbitmines.com/src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.2000x419.png similarity index 100% rename from src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.2000x419.png rename to orbitmines.com/src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.2000x419.png diff --git a/src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3436x720.png b/orbitmines.com/src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3436x720.png similarity index 100% rename from src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3436x720.png rename to orbitmines.com/src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3436x720.png diff --git a/src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3800x634.png b/orbitmines.com/src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3800x634.png similarity index 100% rename from src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3800x634.png rename to orbitmines.com/src/lib/organizations/orbitmines/logo/legacy/orbitmines.logo.legacy.3800x634.png diff --git a/src/lib/organizations/orbitmines/logo/orbitmines.logo.2048x1152.png b/orbitmines.com/src/lib/organizations/orbitmines/logo/orbitmines.logo.2048x1152.png similarity index 100% rename from src/lib/organizations/orbitmines/logo/orbitmines.logo.2048x1152.png rename to orbitmines.com/src/lib/organizations/orbitmines/logo/orbitmines.logo.2048x1152.png diff --git a/src/lib/organizations/orbitmines/logo/orbitmines.logo.3000x1000.png b/orbitmines.com/src/lib/organizations/orbitmines/logo/orbitmines.logo.3000x1000.png similarity index 100% rename from src/lib/organizations/orbitmines/logo/orbitmines.logo.3000x1000.png rename to orbitmines.com/src/lib/organizations/orbitmines/logo/orbitmines.logo.3000x1000.png diff --git a/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.16x15.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.16x15.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.16x15.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.16x15.png diff --git a/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.848x782.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.848x782.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.848x782.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.diamond.848x782.png diff --git a/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.16x15.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.16x15.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.16x15.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.16x15.png diff --git a/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.848x782.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.848x782.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.848x782.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.emerald.848x782.png diff --git a/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.16x15.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.16x15.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.16x15.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.16x15.png diff --git a/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.848x782.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.848x782.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.848x782.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.gold.848x782.png diff --git a/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.16x15.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.16x15.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.16x15.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.16x15.png diff --git a/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.848x782.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.848x782.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.848x782.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/miscellaneous/orbitmines.minecraft.iron.848x782.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.creative.1000x1000.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.creative.1000x1000.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.creative.1000x1000.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.creative.1000x1000.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.1000x1000.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.1000x1000.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.1000x1000.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.1000x1000.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.2.1000x1000.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.2.1000x1000.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.2.1000x1000.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.fog.2.1000x1000.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.kitpvp.1000x1000.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.kitpvp.1000x1000.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.kitpvp.1000x1000.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.kitpvp.1000x1000.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.minigames.1000x1000.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.minigames.1000x1000.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.minigames.1000x1000.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.minigames.1000x1000.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.prison.1000x1000.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.prison.1000x1000.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.prison.1000x1000.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.prison.1000x1000.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.skyblock.1000x1000.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.skyblock.1000x1000.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.skyblock.1000x1000.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.skyblock.1000x1000.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.survival.1000x1000.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.survival.1000x1000.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.survival.1000x1000.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/icon/orbitmines.minecraft.server.icon.survival.1000x1000.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.creative.1000x300.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.creative.1000x300.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.creative.1000x300.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.creative.1000x300.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.fog.1000x300.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.fog.1000x300.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.fog.1000x300.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.fog.1000x300.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.kitpvp.1000x300.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.kitpvp.1000x300.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.kitpvp.1000x300.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.kitpvp.1000x300.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.minigames.1000x300.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.minigames.1000x300.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.minigames.1000x300.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.minigames.1000x300.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.prison.1000x300.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.prison.1000x300.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.prison.1000x300.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.prison.1000x300.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.skyblock.1000x300.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.skyblock.1000x300.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.skyblock.1000x300.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.skyblock.1000x300.png diff --git a/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.survival.1000x300.png b/orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.survival.1000x300.png similarity index 100% rename from src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.survival.1000x300.png rename to orbitmines.com/src/lib/organizations/orbitmines/minecraft/server/logo/orbitmines.minecraft.server.logo.survival.1000x300.png diff --git a/src/lib/organizations/orcid/5008697.zip b/orbitmines.com/src/lib/organizations/orcid/5008697.zip similarity index 100% rename from src/lib/organizations/orcid/5008697.zip rename to orbitmines.com/src/lib/organizations/orcid/5008697.zip diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-128x128.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-16x16.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-24x24.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-32x32.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-64x64.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-128x128.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-16x16.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-24x24.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-32x32.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-32x32.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-32x32.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-32x32.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.gif b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.gif similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.gif rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.gif diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-64x64.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-vector.svg b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-vector.svg similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-vector.svg rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-bw-vector.svg diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon-vector.svg b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-vector.svg similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon-vector.svg rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon-vector.svg diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_128x128.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_128x128.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_128x128.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_128x128.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_24x24.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_24x24.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_24x24.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_24x24.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_32x32.png b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_32x32.png similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_32x32.png rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_32x32.png diff --git a/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_vector.svg b/orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_vector.svg similarity index 100% rename from src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_vector.svg rename to orbitmines.com/src/lib/organizations/orcid/5008697/ORCID-iD_icon_reversed_vector.svg diff --git a/src/lib/organizations/papers-we-love/6187757.png b/orbitmines.com/src/lib/organizations/papers-we-love/6187757.png similarity index 100% rename from src/lib/organizations/papers-we-love/6187757.png rename to orbitmines.com/src/lib/organizations/papers-we-love/6187757.png diff --git a/src/lib/organizations/preposterous-universe/download.jpeg b/orbitmines.com/src/lib/organizations/preposterous-universe/download.jpeg similarity index 100% rename from src/lib/organizations/preposterous-universe/download.jpeg rename to orbitmines.com/src/lib/organizations/preposterous-universe/download.jpeg diff --git a/src/lib/organizations/santa-fe-institute/0_OgRM7UU-SsqK46La.png b/orbitmines.com/src/lib/organizations/santa-fe-institute/0_OgRM7UU-SsqK46La.png similarity index 100% rename from src/lib/organizations/santa-fe-institute/0_OgRM7UU-SsqK46La.png rename to orbitmines.com/src/lib/organizations/santa-fe-institute/0_OgRM7UU-SsqK46La.png diff --git a/src/lib/organizations/semf/semf_icon.jpg b/orbitmines.com/src/lib/organizations/semf/semf_icon.jpg similarity index 100% rename from src/lib/organizations/semf/semf_icon.jpg rename to orbitmines.com/src/lib/organizations/semf/semf_icon.jpg diff --git a/src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square.jpg b/orbitmines.com/src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square.jpg similarity index 100% rename from src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square.jpg rename to orbitmines.com/src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square.jpg diff --git a/src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.png b/orbitmines.com/src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.png similarity index 100% rename from src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.png rename to orbitmines.com/src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.png diff --git a/src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.xcf b/orbitmines.com/src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.xcf similarity index 100% rename from src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.xcf rename to orbitmines.com/src/lib/organizations/strange-loop/strange_loop_logo_final_color_no_year_square2.xcf diff --git a/orbitmines.com/src/lib/organizations/temp.ts b/orbitmines.com/src/lib/organizations/temp.ts new file mode 100644 index 0000000..39a0e51 --- /dev/null +++ b/orbitmines.com/src/lib/organizations/temp.ts @@ -0,0 +1,69 @@ + +const string = "### Literary Exposure\n" + + "- [String Diagram Rewrite Theory II: Rewriting with Symmetric Monoidal Structure](https://arxiv.org/abs/2104.14686) ; *Filippo Bonchi, Fabio Gadducci, Aleks Kissinger, Pawel Sobocinski, Fabio Zanasi*\n" + + "- [ChypCanvas: Composing Hypergraphs, Proving Theorems (2023)](https://act2023.github.io/papers/paper25.pdf) ; *Aleks Kissinger*\n" + + "- [Observer Theory (2023)](https://writings.stephenwolfram.com/2023/12/observer-theory/) ; *Stephen Wolfram*\n" + + "- :wasm: [Wasm SpecTec: Engineering a Formal Language Standard](https://arxiv.org/pdf/2311.07223.pdf) ; *Joachim Breitner, Philippa Gardner, Jaehyun Lee, Sam Lindley, Matija Pretnar, Xiaojia Rao, Andreas Rossberg, Sukyoung Ryu, Wonho Shin, Conrad Watt, Dongjun Youn*\n" + + "\n" + + "- :youtube: :mindscape: [Mindscape 259 | Adam Frank on What Aliens Might Be Like (2023)](https://www.youtube.com/watch?v=UzmlA3g2nRE) ; *Adam Frank and Sean Carroll*\n" + + "- :youtube: [Animation vs. Physics (2023)](https://www.youtube.com/watch?v=ErMSHiQRnc8) ; *Alan Becker + Team*\n" + + "- :youtube: :3b1b: [Why light can “slow down”, and why it depends on color | Optics puzzles (2023)](https://www.youtube.com/watch?v=KTzGBJPuJwM)\n" + + "- :youtube: :lex_fridman_podcast: [Lee Cronin: Controversial Nature Paper on Evolution of Life and Universe | Lex Fridman Podcast #404 (2023)](https://www.youtube.com/watch?v=CGiDqhSdLHk) ; *Lee Cronin, Lex Fridman*\n" + + "- :youtube: :topos_institute: [Berkeley Seminar: David Jaz Myers, 8/7/2023 (2023)](https://www.youtube.com/watch?v=WvniD62U_W4) ; *David Jaz Myers*\n" + + "\n" + + "- [Yugoslavia’s Digital Twin (2023)](https://www.thedial.world/issue-9/yugolsav-wars-yu-domain-history-icann) ; *Kaloyan Kolev*\n" + + "- [Physics explains why there is no information on social media (2021)](https://www.zdnet.com/article/physics-explains-why-there-is-no-information-on-social-media/) ; *Tiernan Ray*\n" + + "- [How To Ask Questions The Smart Way (2001-2014)](http://www.catb.org/~esr/faqs/smart-questions.html) ; *Eric S. Raymond, Rick Moen*\n" + + "\n" + + "- :wikipedia: Wikipedia Articles: [Computability_in_Europe](https://en.wikipedia.org/wiki/Computability_in_Europe), [Elvira_Mayordomo](https://en.wikipedia.org/wiki/Elvira_Mayordomo), [Geoff_Smith_(mathematician)](https://en.wikipedia.org/wiki/Geoff_Smith_(mathematician)), [Louis_Kauffman](https://en.wikipedia.org/wiki/Louis_Kauffman), [Nicolas_Gisin](https://en.wikipedia.org/wiki/Nicolas_Gisin), [Parallel_transport](https://en.wikipedia.org/wiki/Parallel_transport), [Single_pushout_graph_rewriting](https://en.wikipedia.org/wiki/Single_pushout_graph_rewriting), [Terence_Tao](https://en.wikipedia.org/wiki/Terence_Tao)\n" + + "\n" + + "### :twitch:/:youtube: Livestreams\n" + + "- :youtube: :semf: [Complexity & Mathematics | Community Livestream (2023)](https://www.youtube.com/watch?v=MWQ7XFjkOhs)\n" + + "- :youtube: :semf: [Holiday Special Livestream (2023)](https://www.youtube.com/watch?v=m_rATW4Nrqk)\n" + + "\n" + + "- :youtube: [Just Chatting | Tesla AI Day 2022 | Science & Technology (2022)](https://www.youtube.com/watch?v=lSXwIzww6Us) - *George Hotz*\n" + + "- :youtube: [Programming | Mistral mixtral on a tinybox | AMD P2P multi-GPU mixtral-8x7b-32kseqlen (2023)](https://www.youtube.com/watch?v=H40QRJFzThQ) - *George Hotz*\n" + + "- :youtube: [Programming | what is the Q* algorithm? OpenAI Q Star Algorithm | Mistral 7B | PRM800K (2023)](https://www.youtube.com/watch?v=2QO3vzwHXhg) - *George Hotz*\n" + + "- :youtube: [Just Chatting | effective accelerationism | e/acc | Techno-pessimism | Deceleration (2023)](https://www.youtube.com/watch?v=YrWEDOQQ8pw) - *George Hotz*\n" + + "- :youtube: [Science | Thermodynamics is to Energy as ??? is to Intelligence (2023)](https://www.youtube.com/watch?v=vn9Dq24RDn8) - *George Hotz*\n" + + "- :youtube: [Science | Thermodynamics is to Energy as Entropics is to Intelligence | Part 2 (2023)](https://www.youtube.com/watch?v=mEoiQ_PZNTE) - *George Hotz*\n" + + "- :youtube: :tinycorp: [Programming | a tiny tour through tinygrad (noob lesson) (2023)](https://www.youtube.com/watch?v=-MhwhiReY-s) - *George Hotz*\n" + + "- :youtube: :tinycorp: [Programming | tinygrad: writing tutorials for noobs (2023)](https://www.youtube.com/watch?v=Sk35MKtCXfQ) - *George Hotz*\n" + + "- :youtube: :tinycorp: [Rant | Complaining about how terrible Qualcomm is | The business world (2023)](https://www.youtube.com/watch?v=rzb2cuT9vaY) - *George Hotz*\n" + + "- :youtube: :tinycorp: [Chatting | challenges hiring people, vision, building a company tiny corp tinygrad.org (2023)](https://www.youtube.com/watch?v=4_6eY-8dibI) - *George Hotz*\n" + + "- :youtube: :tinycorp: [Reading & Talking | let's read ML papers (2023)](https://www.youtube.com/watch?v=YrWEDOQQ8pw) - *George Hotz*\n"; + +const res = string.split('\n') + .filter(l => l.startsWith('-')) + .map(l => l.trim()) + .map(l => { + const [title, year, link] = [...l.matchAll(/\[(.+)\s(.+)]\((.+)\)/g)] + .map(m => [m[1], m[2], m[3]])[0]; + const organizations = [...l.matchAll(/:([a-z_]+):/g)] + .map(m => m[1]); + // .map(key => (ORGANIZATIONS as any)[key]!); + const authors = [...l.matchAll(/\*(.+)\*$/g)] + .map(m => m[1]) + .join() + .replaceAll(/(\s(and|&)\s)/g, ",") + .split(",") + .map(name => name.trim()); + + const ref = title + .replaceAll(/[|&':{}()#",?*$%^@;\[\]/\\.\"\']/g, "") + .replace(/\s{2,}/g, ' ') + .replaceAll(/[- ]/g, "_") + .toUpperCase(); + + // return `${ref}: { + // reference: { + // title: '${title}', + // authors: [${authors.map(author => `{name: '${author}'}`).join(',')}], + // organizations: [${organizations.map(org => `ORGANIZATIONS.${org}`)}], + // year: '${year}', + // link: "${link}" + // }, status: Viewed.VIEWED, viewed_at: "2023, December" + // }` + return `REFERENCES.${ref}`; + }).join(',\n') +console.log(res); \ No newline at end of file diff --git a/src/lib/organizations/tinycorp/132956020.jpeg b/orbitmines.com/src/lib/organizations/tinycorp/132956020.jpeg similarity index 100% rename from src/lib/organizations/tinycorp/132956020.jpeg rename to orbitmines.com/src/lib/organizations/tinycorp/132956020.jpeg diff --git a/src/lib/organizations/topos.institute/topos_favicon.ico b/orbitmines.com/src/lib/organizations/topos.institute/topos_favicon.ico similarity index 100% rename from src/lib/organizations/topos.institute/topos_favicon.ico rename to orbitmines.com/src/lib/organizations/topos.institute/topos_favicon.ico diff --git a/src/lib/organizations/twitch/twitch-brand-assets.zip b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets.zip similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets.zip rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets.zip diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ai b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ai similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ai rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ai diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ase b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ase similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ase rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Color Palette/TwitchColorPalette.ase diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Guidelines (Speedrun Edition)/Twitch_Guidelines_Speedrun_v2.pdf b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Guidelines (Speedrun Edition)/Twitch_Guidelines_Speedrun_v2.pdf similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Guidelines (Speedrun Edition)/Twitch_Guidelines_Speedrun_v2.pdf rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Guidelines (Speedrun Edition)/Twitch_Guidelines_Speedrun_v2.pdf diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Black Ops/TwitchGlitchBlackOps.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/Purple/TwitchGlitchPurple.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/glitch/White/TwitchGlitchWhite.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/TwitchExtrudedWordmarkBlackOps.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/TwitchExtrudedWordmarkPurple.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch-Wordmark-BlackOps.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch-Wordmark-BlackOps.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch-Wordmark-BlackOps.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch-Wordmark-BlackOps.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Black Ops/Twitch_UnextrudedWordmarkBlackOps.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple-01.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple-01.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple-01.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple-01.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/Twitch_UnextrudedWordmarkPurple.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/Brand Assets/Logos/wordmark/Wordmark/White/Twitch-Wordmark-White.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/._Brand Assets b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/._Brand Assets similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/._Brand Assets rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/._Brand Assets diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Color Palette b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Color Palette similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Color Palette rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Color Palette diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Guidelines (Speedrun Edition) b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Guidelines (Speedrun Edition) similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Guidelines (Speedrun Edition) rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Guidelines (Speedrun Edition) diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Logos b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Logos similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Logos rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/._Logos diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ai b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ai similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ai rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ai diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ase b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ase similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ase rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Color Palette/._TwitchColorPalette.ase diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Guidelines (Speedrun Edition)/._Twitch_Guidelines_Speedrun_v2.pdf b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Guidelines (Speedrun Edition)/._Twitch_Guidelines_Speedrun_v2.pdf similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Guidelines (Speedrun Edition)/._Twitch_Guidelines_Speedrun_v2.pdf rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Guidelines (Speedrun Edition)/._Twitch_Guidelines_Speedrun_v2.pdf diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._glitch b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._glitch similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._glitch rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._glitch diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._wordmark b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._wordmark similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._wordmark rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/._wordmark diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Black Ops b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Black Ops similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Black Ops rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Black Ops diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Purple b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Purple similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Purple rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._Purple diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._White b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._White similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._White rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/._White diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Black Ops/._TwitchGlitchBlackOps.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/Purple/._TwitchGlitchPurple.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/glitch/White/._TwitchGlitchWhite.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Extruded Wordmark (Primary Logo) b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Extruded Wordmark (Primary Logo) similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Extruded Wordmark (Primary Logo) rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Extruded Wordmark (Primary Logo) diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Wordmark b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Wordmark similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Wordmark rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/._Wordmark diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Black Ops b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Black Ops similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Black Ops rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Black Ops diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Twitch Purple b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Twitch Purple similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Twitch Purple rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/._Twitch Purple diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Black Ops/._TwitchExtrudedWordmarkBlackOps.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Extruded Wordmark (Primary Logo)/Twitch Purple/._TwitchExtrudedWordmarkPurple.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Black Ops b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Black Ops similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Black Ops rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Black Ops diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Twitch Purple b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Twitch Purple similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Twitch Purple rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._Twitch Purple diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._White b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._White similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._White rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/._White diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch-Wordmark-BlackOps.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch-Wordmark-BlackOps.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch-Wordmark-BlackOps.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch-Wordmark-BlackOps.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Black Ops/._Twitch_UnextrudedWordmarkBlackOps.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple-01.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple-01.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple-01.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple-01.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/Twitch Purple/._Twitch_UnextrudedWordmarkPurple.svg diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.eps b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.eps similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.eps rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.eps diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.png b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.png similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.png rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.png diff --git a/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-brand-assets/__MACOSX/Brand Assets/Logos/wordmark/Wordmark/White/._Twitch-Wordmark-White.svg diff --git a/src/lib/organizations/twitch/twitch-white-icon.svg b/orbitmines.com/src/lib/organizations/twitch/twitch-white-icon.svg similarity index 100% rename from src/lib/organizations/twitch/twitch-white-icon.svg rename to orbitmines.com/src/lib/organizations/twitch/twitch-white-icon.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021.zip b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021.zip similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021.zip rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021.zip diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - black.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - black.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - black.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - black.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - blue.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/EPS/2021 Twitter logo - white.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - black.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - black.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - black.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - black.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - blue.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PNG/2021 Twitter logo - white.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - black.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - black.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - black.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - black.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - blue.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/PSD/2021 Twitter logo - white.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo black.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo black.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo black.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo black.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo blue.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter logo/SVG/Logo white.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - blue.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - circle/Twitter social icons - circle - white.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - blue.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - rounded square/Twitter social icons - rounded square - white.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - blue.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/Twitter social icons/Twitter social icons - square/Twitter social icons - square - white.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter logo b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter logo similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter logo rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter logo diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter social icons b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter social icons similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter social icons rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/._Twitter social icons diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._EPS b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._EPS similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._EPS rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._EPS diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PNG b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PNG similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PNG rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PNG diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PSD b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PSD similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PSD rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._PSD diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._SVG b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._SVG similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._SVG rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/._SVG diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - black.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - black.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - black.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - black.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - blue.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/EPS/._2021 Twitter logo - white.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - black.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - black.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - black.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - black.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - blue.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PNG/._2021 Twitter logo - white.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - black.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - black.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - black.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - black.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - blue.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/PSD/._2021 Twitter logo - white.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo black.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo black.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo black.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo black.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo blue.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter logo/SVG/._Logo white.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - circle b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - circle similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - circle rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - circle diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - rounded square b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - rounded square similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - rounded square rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - rounded square diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - square b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - square similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - square rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/._Twitter social icons - square diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - blue.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - circle/._Twitter social icons - circle - white.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - blue.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - rounded square/._Twitter social icons - rounded square - white.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - blue.svg diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.ai diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.eps diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.png diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.psd diff --git a/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-logo-01282021/__MACOSX/Twitter social icons/Twitter social icons - square/._Twitter social icons - square - white.svg diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021.zip b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021.zip similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021.zip rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021.zip diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - brand loves Twitter.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - centered.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - In partnership with - left.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter after.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - one partner - Twitter first.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - centered.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - three partners - In partnership with - left.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter after.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/2021 Twitter partnership lockups - two partners - Twitter first.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/PartnershipPairingLockup_Templates_Helvetica.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/PartnershipPairingLockup_Templates_Helvetica.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/PartnershipPairingLockup_Templates_Helvetica.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/Twitter partnership lockups/PartnershipPairingLockup_Templates_Helvetica.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/._Twitter partnership lockups b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/._Twitter partnership lockups similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/._Twitter partnership lockups rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/._Twitter partnership lockups diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - brand loves Twitter.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - centered.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - In partnership with - left.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter after.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - one partner - Twitter first.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - centered.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - three partners - In partnership with - left.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter after.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.ai diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.png b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.png similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._2021 Twitter partnership lockups - two partners - Twitter first.png diff --git a/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._PartnershipPairingLockup_Templates_Helvetica.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._PartnershipPairingLockup_Templates_Helvetica.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._PartnershipPairingLockup_Templates_Helvetica.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-partnership-lockups-01272021/__MACOSX/Twitter partnership lockups/._PartnershipPairingLockup_Templates_Helvetica.ai diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021.zip b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021.zip similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021.zip rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021.zip diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/._twitter-spaces-12152021 b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/._twitter-spaces-12152021 similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/._twitter-spaces-12152021 rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/._twitter-spaces-12152021 diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._EPS b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._EPS similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._EPS rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._EPS diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PNG b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PNG similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PNG rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PNG diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PSD b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PSD similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PSD rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._PSD diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._SVG b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._SVG similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._SVG rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._SVG diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._twitterspaces-external-playbook-dec2021.pdf b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._twitterspaces-external-playbook-dec2021.pdf similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._twitterspaces-external-playbook-dec2021.pdf rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/._twitterspaces-external-playbook-dec2021.pdf diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - black.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - black.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - black.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - black.eps diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - blue.eps diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/EPS/._2021 TwitterSpaces Logo - white.eps diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - black.png b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - black.png similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - black.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - black.png diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - blue.png diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PNG/._2021 TwitterSpaces Logo - white.png diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - black.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - black.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - black.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - black.psd diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - blue.psd diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/PSD/._2021 TwitterSpaces Logo - white.psd diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - black.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - black.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - black.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - black.svg diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - blue.svg diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/__MACOSX/twitter-spaces-12152021/SVG/._2021 TwitterSpaces Logo - white.svg diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - black.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - black.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - black.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - black.eps diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - blue.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - blue.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - blue.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - blue.eps diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - white.eps b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - white.eps similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - white.eps rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/EPS/2021 TwitterSpaces Logo - white.eps diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - black.png b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - black.png similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - black.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - black.png diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - blue.png b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - blue.png similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - blue.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - blue.png diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - white.png b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - white.png similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - white.png rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PNG/2021 TwitterSpaces Logo - white.png diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - black.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - black.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - black.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - black.psd diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - blue.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - blue.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - blue.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - blue.psd diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - white.psd b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - white.psd similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - white.psd rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/PSD/2021 TwitterSpaces Logo - white.psd diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - black.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - black.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - black.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - black.svg diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - blue.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - blue.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - blue.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - blue.svg diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - white.svg b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - white.svg similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - white.svg rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/SVG/2021 TwitterSpaces Logo - white.svg diff --git a/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/twitterspaces-external-playbook-dec2021.pdf b/orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/twitterspaces-external-playbook-dec2021.pdf similarity index 100% rename from src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/twitterspaces-external-playbook-dec2021.pdf rename to orbitmines.com/src/lib/organizations/twitter/twitter-spaces-12152021/twitter-spaces-12152021/twitterspaces-external-playbook-dec2021.pdf diff --git a/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021.zip b/orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021.zip similarity index 100% rename from src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021.zip rename to orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021.zip diff --git a/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/2021 Twitter Tweet template - Helvetica.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/2021 Twitter Tweet template - Helvetica.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/2021 Twitter Tweet template - Helvetica.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/2021 Twitter Tweet template - Helvetica.ai diff --git a/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-55Roman.otf b/orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-55Roman.otf similarity index 100% rename from src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-55Roman.otf rename to orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-55Roman.otf diff --git a/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-75Bold.otf b/orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-75Bold.otf similarity index 100% rename from src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-75Bold.otf rename to orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/Twitter Tweet template - Helvetica/Fonts/HelveticaNeueLTPro-75Bold.otf diff --git a/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/._Twitter Tweet template - Helvetica b/orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/._Twitter Tweet template - Helvetica similarity index 100% rename from src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/._Twitter Tweet template - Helvetica rename to orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/._Twitter Tweet template - Helvetica diff --git a/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._2021 Twitter Tweet template - Helvetica.ai b/orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._2021 Twitter Tweet template - Helvetica.ai similarity index 100% rename from src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._2021 Twitter Tweet template - Helvetica.ai rename to orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._2021 Twitter Tweet template - Helvetica.ai diff --git a/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._Fonts b/orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._Fonts similarity index 100% rename from src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._Fonts rename to orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/._Fonts diff --git a/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-55Roman.otf b/orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-55Roman.otf similarity index 100% rename from src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-55Roman.otf rename to orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-55Roman.otf diff --git a/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-75Bold.otf b/orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-75Bold.otf similarity index 100% rename from src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-75Bold.otf rename to orbitmines.com/src/lib/organizations/twitter/twitter-tweet-template-helvetica-01272021/__MACOSX/Twitter Tweet template - Helvetica/Fonts/._HelveticaNeueLTPro-75Bold.otf diff --git a/src/lib/organizations/twitter/x/x-logo.zip b/orbitmines.com/src/lib/organizations/twitter/x/x-logo.zip similarity index 100% rename from src/lib/organizations/twitter/x/x-logo.zip rename to orbitmines.com/src/lib/organizations/twitter/x/x-logo.zip diff --git a/src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-black.png b/orbitmines.com/src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-black.png similarity index 100% rename from src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-black.png rename to orbitmines.com/src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-black.png diff --git a/src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-white.png b/orbitmines.com/src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-white.png similarity index 100% rename from src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-white.png rename to orbitmines.com/src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo-white.png diff --git a/src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo.svg b/orbitmines.com/src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo.svg similarity index 100% rename from src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo.svg rename to orbitmines.com/src/lib/organizations/twitter/x/x-logo/__MACOSX/._logo.svg diff --git a/src/lib/organizations/twitter/x/x-logo/logo-black.png b/orbitmines.com/src/lib/organizations/twitter/x/x-logo/logo-black.png similarity index 100% rename from src/lib/organizations/twitter/x/x-logo/logo-black.png rename to orbitmines.com/src/lib/organizations/twitter/x/x-logo/logo-black.png diff --git a/src/lib/organizations/twitter/x/x-logo/logo-white.png b/orbitmines.com/src/lib/organizations/twitter/x/x-logo/logo-white.png similarity index 100% rename from src/lib/organizations/twitter/x/x-logo/logo-white.png rename to orbitmines.com/src/lib/organizations/twitter/x/x-logo/logo-white.png diff --git a/src/lib/organizations/twitter/x/x-logo/logo.svg b/orbitmines.com/src/lib/organizations/twitter/x/x-logo/logo.svg similarity index 100% rename from src/lib/organizations/twitter/x/x-logo/logo.svg rename to orbitmines.com/src/lib/organizations/twitter/x/x-logo/logo.svg diff --git a/src/lib/organizations/wasm/371632.svg b/orbitmines.com/src/lib/organizations/wasm/371632.svg similarity index 100% rename from src/lib/organizations/wasm/371632.svg rename to orbitmines.com/src/lib/organizations/wasm/371632.svg diff --git a/src/lib/organizations/wasm/file-type-wasm.svg b/orbitmines.com/src/lib/organizations/wasm/file-type-wasm.svg similarity index 100% rename from src/lib/organizations/wasm/file-type-wasm.svg rename to orbitmines.com/src/lib/organizations/wasm/file-type-wasm.svg diff --git a/src/lib/organizations/wasm/webassembly (1).svg b/orbitmines.com/src/lib/organizations/wasm/webassembly (1).svg similarity index 100% rename from src/lib/organizations/wasm/webassembly (1).svg rename to orbitmines.com/src/lib/organizations/wasm/webassembly (1).svg diff --git a/src/lib/organizations/wasm/webassembly-icon.png b/orbitmines.com/src/lib/organizations/wasm/webassembly-icon.png similarity index 100% rename from src/lib/organizations/wasm/webassembly-icon.png rename to orbitmines.com/src/lib/organizations/wasm/webassembly-icon.png diff --git a/src/lib/organizations/wasm/webassembly-icon.svg b/orbitmines.com/src/lib/organizations/wasm/webassembly-icon.svg similarity index 100% rename from src/lib/organizations/wasm/webassembly-icon.svg rename to orbitmines.com/src/lib/organizations/wasm/webassembly-icon.svg diff --git a/src/lib/organizations/wasm/webassembly.256x256.png b/orbitmines.com/src/lib/organizations/wasm/webassembly.256x256.png similarity index 100% rename from src/lib/organizations/wasm/webassembly.256x256.png rename to orbitmines.com/src/lib/organizations/wasm/webassembly.256x256.png diff --git a/src/lib/organizations/wasm/webassembly.svg b/orbitmines.com/src/lib/organizations/wasm/webassembly.svg similarity index 100% rename from src/lib/organizations/wasm/webassembly.svg rename to orbitmines.com/src/lib/organizations/wasm/webassembly.svg diff --git a/src/lib/organizations/wolfram-institute/channels4_profile.jpg b/orbitmines.com/src/lib/organizations/wolfram-institute/channels4_profile.jpg similarity index 100% rename from src/lib/organizations/wolfram-institute/channels4_profile.jpg rename to orbitmines.com/src/lib/organizations/wolfram-institute/channels4_profile.jpg diff --git a/src/lib/organizations/youtube/YouTube_full-color_icon_(2017).svg b/orbitmines.com/src/lib/organizations/youtube/YouTube_full-color_icon_(2017).svg similarity index 100% rename from src/lib/organizations/youtube/YouTube_full-color_icon_(2017).svg rename to orbitmines.com/src/lib/organizations/youtube/YouTube_full-color_icon_(2017).svg diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo.zip b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo.zip similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo.zip rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo.zip diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/._youtube_full_color_dark_logo b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/._youtube_full_color_dark_logo similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/._youtube_full_color_dark_logo rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/._youtube_full_color_dark_logo diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._digital_and_tv b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._digital_and_tv similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._digital_and_tv rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._digital_and_tv diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._print b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._print similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._print rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/._print diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.ai diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.eps diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.png b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.png similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.png rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/digital_and_tv/._yt_logo_rgb_dark.png diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.ai diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_cmyk_dark.eps diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.ai diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/__MACOSX/youtube_full_color_dark_logo/print/._yt_logo_pms_dark.eps diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.ai diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.eps diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.png b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.png similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.png rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/digital_and_tv/yt_logo_rgb_dark.png diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.ai diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_cmyk_dark.eps diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.ai diff --git a/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-dark-logo/youtube_full_color_dark_logo/print/yt_logo_pms_dark.eps diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo.zip b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo.zip similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo.zip rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo.zip diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/._youtube_full_color_light_logo b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/._youtube_full_color_light_logo similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/._youtube_full_color_light_logo rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/._youtube_full_color_light_logo diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._digital_and_tv b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._digital_and_tv similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._digital_and_tv rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._digital_and_tv diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._print b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._print similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._print rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/._print diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.ai diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.eps diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.png b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.png similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.png rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/digital_and_tv/._yt_logo_rgb_light.png diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.ai diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_cmyk_light.eps diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.ai diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/__MACOSX/youtube_full_color_light_logo/print/._yt_logo_pms_light.eps diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.ai diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.eps diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.png b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.png similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.png rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/digital_and_tv/yt_logo_rgb_light.png diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.ai diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_cmyk_light.eps diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.ai diff --git a/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-full-color-light-logo/youtube_full_color_light_logo/print/yt_logo_pms_light.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos.zip b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos.zip similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos.zip rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos.zip diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/._youtube_monochrome_logos b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/._youtube_monochrome_logos similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/._youtube_monochrome_logos rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/._youtube_monochrome_logos diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._digital_and_tv b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._digital_and_tv similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._digital_and_tv rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._digital_and_tv diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._print b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._print similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._print rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/._print diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.png b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.png similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.png rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_dark.png diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.png b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.png similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.png rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/digital_and_tv/._yt_logo_mono_light.png diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_dark.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_cmyk_mono_light.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_dark.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/__MACOSX/youtube_monochrome_logos/print/._yt_logo_pms_mono_light.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.png b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.png similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.png rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_dark.png diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.png b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.png similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.png rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/digital_and_tv/yt_logo_mono_light.png diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_dark.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_cmyk_mono_light.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_dark.eps diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.ai b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.ai similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.ai rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.ai diff --git a/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.eps b/orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.eps similarity index 100% rename from src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.eps rename to orbitmines.com/src/lib/organizations/youtube/brand-monochrome-logos/youtube_monochrome_logos/print/yt_logo_pms_mono_light.eps diff --git a/src/lib/organizations/youtube/youtube-app-white-icon.svg b/orbitmines.com/src/lib/organizations/youtube/youtube-app-white-icon.svg similarity index 100% rename from src/lib/organizations/youtube/youtube-app-white-icon.svg rename to orbitmines.com/src/lib/organizations/youtube/youtube-app-white-icon.svg diff --git a/src/lib/organizations/youtube/youtube-logo-2431.svg b/orbitmines.com/src/lib/organizations/youtube/youtube-logo-2431.svg similarity index 100% rename from src/lib/organizations/youtube/youtube-logo-2431.svg rename to orbitmines.com/src/lib/organizations/youtube/youtube-logo-2431.svg diff --git a/src/lib/organizations/zulip/Zulip-icon-square.svg b/orbitmines.com/src/lib/organizations/zulip/Zulip-icon-square.svg similarity index 100% rename from src/lib/organizations/zulip/Zulip-icon-square.svg rename to orbitmines.com/src/lib/organizations/zulip/Zulip-icon-square.svg diff --git a/src/lib/paper/Paper.tsx b/orbitmines.com/src/lib/paper/Paper.tsx similarity index 100% rename from src/lib/paper/Paper.tsx rename to orbitmines.com/src/lib/paper/Paper.tsx diff --git a/src/lib/paper/PaperContent.tsx b/orbitmines.com/src/lib/paper/PaperContent.tsx similarity index 100% rename from src/lib/paper/PaperContent.tsx rename to orbitmines.com/src/lib/paper/PaperContent.tsx diff --git a/src/lib/paper/browser/Exports.tsx b/orbitmines.com/src/lib/paper/browser/Exports.tsx similarity index 100% rename from src/lib/paper/browser/Exports.tsx rename to orbitmines.com/src/lib/paper/browser/Exports.tsx diff --git a/src/lib/paper/layout/Arc.tsx b/orbitmines.com/src/lib/paper/layout/Arc.tsx similarity index 100% rename from src/lib/paper/layout/Arc.tsx rename to orbitmines.com/src/lib/paper/layout/Arc.tsx diff --git a/src/lib/paper/layout/Author.tsx b/orbitmines.com/src/lib/paper/layout/Author.tsx similarity index 100% rename from src/lib/paper/layout/Author.tsx rename to orbitmines.com/src/lib/paper/layout/Author.tsx diff --git a/src/lib/paper/layout/BR.tsx b/orbitmines.com/src/lib/paper/layout/BR.tsx similarity index 100% rename from src/lib/paper/layout/BR.tsx rename to orbitmines.com/src/lib/paper/layout/BR.tsx diff --git a/src/lib/paper/layout/Link.tsx b/orbitmines.com/src/lib/paper/layout/Link.tsx similarity index 100% rename from src/lib/paper/layout/Link.tsx rename to orbitmines.com/src/lib/paper/layout/Link.tsx diff --git a/src/lib/paper/layout/Organization.tsx b/orbitmines.com/src/lib/paper/layout/Organization.tsx similarity index 100% rename from src/lib/paper/layout/Organization.tsx rename to orbitmines.com/src/lib/paper/layout/Organization.tsx diff --git a/src/lib/paper/layout/Paragraph.tsx b/orbitmines.com/src/lib/paper/layout/Paragraph.tsx similarity index 100% rename from src/lib/paper/layout/Paragraph.tsx rename to orbitmines.com/src/lib/paper/layout/Paragraph.tsx diff --git a/src/lib/paper/layout/Reference.tsx b/orbitmines.com/src/lib/paper/layout/Reference.tsx similarity index 100% rename from src/lib/paper/layout/Reference.tsx rename to orbitmines.com/src/lib/paper/layout/Reference.tsx diff --git a/src/lib/paper/layout/Section.tsx b/orbitmines.com/src/lib/paper/layout/Section.tsx similarity index 100% rename from src/lib/paper/layout/Section.tsx rename to orbitmines.com/src/lib/paper/layout/Section.tsx diff --git a/src/lib/paper/layout/TODO.tsx b/orbitmines.com/src/lib/paper/layout/TODO.tsx similarity index 100% rename from src/lib/paper/layout/TODO.tsx rename to orbitmines.com/src/lib/paper/layout/TODO.tsx diff --git a/src/lib/paper/views/Browser.tsx b/orbitmines.com/src/lib/paper/views/Browser.tsx similarity index 100% rename from src/lib/paper/views/Browser.tsx rename to orbitmines.com/src/lib/paper/views/Browser.tsx diff --git a/src/lib/paper/views/ExportablePaper.tsx b/orbitmines.com/src/lib/paper/views/ExportablePaper.tsx similarity index 100% rename from src/lib/paper/views/ExportablePaper.tsx rename to orbitmines.com/src/lib/paper/views/ExportablePaper.tsx diff --git a/src/lib/pdf/DereferenceHtml.tsx b/orbitmines.com/src/lib/pdf/DereferenceHtml.tsx similarity index 100% rename from src/lib/pdf/DereferenceHtml.tsx rename to orbitmines.com/src/lib/pdf/DereferenceHtml.tsx diff --git a/src/lib/pdf/computeExplicitStyles.tsx b/orbitmines.com/src/lib/pdf/computeExplicitStyles.tsx similarity index 100% rename from src/lib/pdf/computeExplicitStyles.tsx rename to orbitmines.com/src/lib/pdf/computeExplicitStyles.tsx diff --git a/src/lib/pdf/dereferenceHtmlElement.tsx b/orbitmines.com/src/lib/pdf/dereferenceHtmlElement.tsx similarity index 100% rename from src/lib/pdf/dereferenceHtmlElement.tsx rename to orbitmines.com/src/lib/pdf/dereferenceHtmlElement.tsx diff --git a/src/lib/syntax-highlighting/CodeBlock.tsx b/orbitmines.com/src/lib/syntax-highlighting/CodeBlock.tsx similarity index 100% rename from src/lib/syntax-highlighting/CodeBlock.tsx rename to orbitmines.com/src/lib/syntax-highlighting/CodeBlock.tsx diff --git a/src/lib/typescript/React.tsx b/orbitmines.com/src/lib/typescript/React.tsx similarity index 100% rename from src/lib/typescript/React.tsx rename to orbitmines.com/src/lib/typescript/React.tsx diff --git a/src/lib/typescript/Replacer.ts b/orbitmines.com/src/lib/typescript/Replacer.ts similarity index 100% rename from src/lib/typescript/Replacer.ts rename to orbitmines.com/src/lib/typescript/Replacer.ts diff --git a/src/modules.d.ts b/orbitmines.com/src/modules.d.ts similarity index 100% rename from src/modules.d.ts rename to orbitmines.com/src/modules.d.ts diff --git a/src/profiles/FadiShawki/FadiShawki.ts b/orbitmines.com/src/profiles/FadiShawki/FadiShawki.ts similarity index 100% rename from src/profiles/FadiShawki/FadiShawki.ts rename to orbitmines.com/src/profiles/FadiShawki/FadiShawki.ts diff --git a/src/profiles/FadiShawki/FadiShawki2.tsx b/orbitmines.com/src/profiles/FadiShawki/FadiShawki2.tsx similarity index 100% rename from src/profiles/FadiShawki/FadiShawki2.tsx rename to orbitmines.com/src/profiles/FadiShawki/FadiShawki2.tsx diff --git a/src/profiles/FadiShawki/fadishawki.profile-picture.png b/orbitmines.com/src/profiles/FadiShawki/fadishawki.profile-picture.png similarity index 100% rename from src/profiles/FadiShawki/fadishawki.profile-picture.png rename to orbitmines.com/src/profiles/FadiShawki/fadishawki.profile-picture.png diff --git a/src/profiles/Profile.tsx b/orbitmines.com/src/profiles/Profile.tsx similarity index 100% rename from src/profiles/Profile.tsx rename to orbitmines.com/src/profiles/Profile.tsx diff --git a/src/profiles/profiles.ts b/orbitmines.com/src/profiles/profiles.ts similarity index 100% rename from src/profiles/profiles.ts rename to orbitmines.com/src/profiles/profiles.ts diff --git a/src/routes/Error.tsx b/orbitmines.com/src/routes/Error.tsx similarity index 100% rename from src/routes/Error.tsx rename to orbitmines.com/src/routes/Error.tsx diff --git a/src/routes/Paper.tsx b/orbitmines.com/src/routes/Paper.tsx similarity index 100% rename from src/routes/Paper.tsx rename to orbitmines.com/src/routes/Paper.tsx diff --git a/src/routes/Profiles.tsx b/orbitmines.com/src/routes/Profiles.tsx similarity index 100% rename from src/routes/Profiles.tsx rename to orbitmines.com/src/routes/Profiles.tsx diff --git a/src/routes/Root.tsx b/orbitmines.com/src/routes/Root.tsx similarity index 100% rename from src/routes/Root.tsx rename to orbitmines.com/src/routes/Root.tsx diff --git a/src/routes/papers/2022.OnIntelligibility.tsx b/orbitmines.com/src/routes/papers/2022.OnIntelligibility.tsx similarity index 100% rename from src/routes/papers/2022.OnIntelligibility.tsx rename to orbitmines.com/src/routes/papers/2022.OnIntelligibility.tsx diff --git a/src/routes/papers/2023.FadiShawki.tsx b/orbitmines.com/src/routes/papers/2023.FadiShawki.tsx similarity index 100% rename from src/routes/papers/2023.FadiShawki.tsx rename to orbitmines.com/src/routes/papers/2023.FadiShawki.tsx diff --git a/src/routes/papers/2023.OnOrbits.tsx b/orbitmines.com/src/routes/papers/2023.OnOrbits.tsx similarity index 100% rename from src/routes/papers/2023.OnOrbits.tsx rename to orbitmines.com/src/routes/papers/2023.OnOrbits.tsx diff --git a/tsconfig.json b/orbitmines.com/tsconfig.json similarity index 100% rename from tsconfig.json rename to orbitmines.com/tsconfig.json diff --git a/useless_junk/generate_chyp.js b/orbitmines.com/useless_junk/generate_chyp.js similarity index 100% rename from useless_junk/generate_chyp.js rename to orbitmines.com/useless_junk/generate_chyp.js From 4b2d7c4551fe0c6030c0e6c16932c12445d22c2b Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 15:11:08 +0100 Subject: [PATCH 122/138] 2024/01/25 - Move everything to a separate orbitmines.com folder. --- README.md | 10 ++++++++-- orbitmines.com/Dockerfile | 11 ----------- 2 files changed, 8 insertions(+), 13 deletions(-) delete mode 100755 orbitmines.com/Dockerfile diff --git a/README.md b/README.md index e93d69e..12666bd 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -![orbitmines.logo.3000x1000.png](src%2Flib%2Forganizations%2Forbitmines%2Flogo%2Forbitmines.logo.3000x1000.png) +![orbitmines.logo.3000x1000.png](./orbitmines.com/src%2Flib%2Forganizations%2Forbitmines%2Flogo%2Forbitmines.logo.3000x1000.png) # orbitmines.com *A public repository for [orbitmines.com](https://orbitmines.com). The hub for OrbitMines' (research) projects.* *Once a Minecraft server, now a research project dedicated to understanding arbitrarily unknown dynamical systems.* -![header](./public/papers/on-orbits-equivalence-and-inconsistencies/images/header.png) +![header](./orbitmines.com/public/papers/on-orbits-equivalence-and-inconsistencies/images/header.png) ## What is this?, What is OrbitMines?, What are Rays? @@ -51,6 +51,12 @@ Most importantly, it is here as infrastructure. Infrastructure for the design an ### Local setup - Running `orbitmines.com` locally on `http://localhost:3000`: + - ```shell + git clone git@github.com:orbitmines/orbitmines.com.git + ``` + - ```shell + cd ./orbitmines/orbitmines.com + ``` - ``` npm install ``` diff --git a/orbitmines.com/Dockerfile b/orbitmines.com/Dockerfile deleted file mode 100755 index cdd4b86..0000000 --- a/orbitmines.com/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM node:20-buster - -WORKDIR /app - -COPY package*.json ./ - -RUN npm install --legacy-peer-deps - -COPY . . - -CMD ["npm", "start"] \ No newline at end of file From 25a570a4e201f24d6cbc8ef51ed0cfe8f861fbc5 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 15:59:16 +0100 Subject: [PATCH 123/138] 2024/01/25 - Move some files around, get tests working --- .gitignore | 2 +- README.md | 6 +- .../javascript/@orbitmines/js/index.ts | 5 + .../@orbitmines/js/package-lock.json | 3760 ++++++++++++++ .../javascript/@orbitmines/js/package.json | 36 + .../javascript/@orbitmines/js/src}/JS.spec.ts | 67 - .../javascript/@orbitmines/js/src}/JS.ts | 3 +- .../@orbitmines/js/src}/errors/errors.ts | 0 .../javascript/@orbitmines/js/tsconfig.json | 26 + .../javascript/@orbitmines/rays/index.ts | 3 + .../@orbitmines/rays/package-lock.json | 4375 +++++++++++++++++ .../javascript/@orbitmines/rays/package.json | 40 + .../@orbitmines/rays/src}/Ray.spec.ts | 91 +- .../javascript/@orbitmines/rays/src}/Ray.ts | 15 +- .../javascript/@orbitmines/rays/tsconfig.json | 25 + orbitmines.com/package-lock.json | 27 +- orbitmines.com/package.json | 11 +- .../explorer/debug/DebugCanvas.tsx | 2 +- orbitmines.com/src/@orbitmines/rays/index.ts | 2 - 19 files changed, 8406 insertions(+), 90 deletions(-) create mode 100644 environments/javascript/@orbitmines/js/index.ts create mode 100644 environments/javascript/@orbitmines/js/package-lock.json create mode 100755 environments/javascript/@orbitmines/js/package.json rename {orbitmines.com/src/@orbitmines/explorer => environments/javascript/@orbitmines/js/src}/JS.spec.ts (84%) rename {orbitmines.com/src/@orbitmines/explorer => environments/javascript/@orbitmines/js/src}/JS.ts (93%) rename {orbitmines.com/src/@orbitmines/explorer => environments/javascript/@orbitmines/js/src}/errors/errors.ts (100%) create mode 100755 environments/javascript/@orbitmines/js/tsconfig.json create mode 100644 environments/javascript/@orbitmines/rays/index.ts create mode 100644 environments/javascript/@orbitmines/rays/package-lock.json create mode 100755 environments/javascript/@orbitmines/rays/package.json rename {orbitmines.com/src/@orbitmines/explorer => environments/javascript/@orbitmines/rays/src}/Ray.spec.ts (97%) rename {orbitmines.com/src/@orbitmines/explorer => environments/javascript/@orbitmines/rays/src}/Ray.ts (98%) create mode 100755 environments/javascript/@orbitmines/rays/tsconfig.json delete mode 100644 orbitmines.com/src/@orbitmines/rays/index.ts diff --git a/.gitignore b/.gitignore index 02be175..9bd5140 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,5 @@ external orbitmines.com/node_modules # Environment -.idea +**/.idea diff --git a/README.md b/README.md index 12666bd..7f70521 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## What is this?, What is OrbitMines?, What are Rays? -A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hyper-/)'Edge', (hyper-/)'Graph', (hyper-/)'Rule', (hyper-/)'Tactic', (hyper-/)..., (hyper-/)'Rewrite' are merged into one thing: a [Ray](https://github.com/orbitmines/orbitmines.com/blob/main/src/%40orbitmines/explorer/Ray.ts). It handles surrounding context, ignorances, equivalences, ..., differentiation (And if it cannot, then it offers a way of implementing it for all of the above). +A simple way of phrasing this, is that the concept of a (hyper-/)'Vertex', (hyper-/)'Edge', (hyper-/)'Graph', (hyper-/)'Rule', (hyper-/)'Tactic', (hyper-/)..., (hyper-/)'Rewrite' are merged into one thing: a [Ray](./environments/javascript/@orbitmines/rays/src/Ray.ts). It handles surrounding context, ignorances, equivalences, ..., differentiation (And if it cannot, then it offers a way of implementing it for all of the above). Most importantly, it is here as infrastructure. Infrastructure for the design and implementation of a different category of (programming) interfaces. @@ -19,7 +19,7 @@ Most importantly, it is here as infrastructure. Infrastructure for the design an - If you prefer **audio-visual mumblings**, see [2024-01-04. What is OrbitMines?, Implementing Aleks Kissinger's Chyp and maybe looking at Tinygrad](https://www.youtube.com/watch?v=O6v_gzlI1kY), or more generally my streams can be found here: [youtube.com/@FadiShawki/streams](https://www.youtube.com/@FadiShawki/streams). -- If you prefer **archaic symbolics: i.e. code**, see [Ray.ts](https://github.com/orbitmines/orbitmines.com/blob/main/src/%40orbitmines/explorer/Ray.ts) (or locally: [local/Ray.ts](./src/@orbitmines/explorer/Ray.ts)), or more generally my/OrbitMines code can be found here [github.com/orbitmines](https://github.com/orbitmines/). +- If you prefer **archaic symbolics: i.e. code**, see [Ray.ts](./environments/javascript/@orbitmines/rays/src/Ray.ts), or more generally my/OrbitMines code can be found here [github.com/orbitmines](https://github.com/orbitmines/). - If you prefer discussions on **Discord**: [discord.orbitmines.com](https://discord.orbitmines.com). @@ -55,7 +55,7 @@ Most importantly, it is here as infrastructure. Infrastructure for the design an git clone git@github.com:orbitmines/orbitmines.com.git ``` - ```shell - cd ./orbitmines/orbitmines.com + cd ./orbitmines.com/orbitmines.com ``` - ``` npm install diff --git a/environments/javascript/@orbitmines/js/index.ts b/environments/javascript/@orbitmines/js/index.ts new file mode 100644 index 0000000..9dfc169 --- /dev/null +++ b/environments/javascript/@orbitmines/js/index.ts @@ -0,0 +1,5 @@ +import JS from './src/JS'; + +export * from './src/errors/errors' + +export default JS; \ No newline at end of file diff --git a/environments/javascript/@orbitmines/js/package-lock.json b/environments/javascript/@orbitmines/js/package-lock.json new file mode 100644 index 0000000..982363b --- /dev/null +++ b/environments/javascript/@orbitmines/js/package-lock.json @@ -0,0 +1,3760 @@ +{ + "name": "@orbitmines/js", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@orbitmines/js", + "version": "0.1.0", + "dependencies": { + "lodash": "^4.17.21" + }, + "devDependencies": { + "@types/jest": "^29.5.11", + "@types/lodash": "^4.14.194", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "typescript": "^5.0.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", + "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.11", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", + "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", + "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001580", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001580.tgz", + "integrity": "sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.645", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.645.tgz", + "integrity": "sha512-EeS1oQDCmnYsRDRy2zTeC336a/4LZ6WKqvSaM1jLocEk5ZuyszkQtCpsqvuvaIXGOUjwtvF6LTcS8WueibXvSw==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-jest": { + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", + "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/environments/javascript/@orbitmines/js/package.json b/environments/javascript/@orbitmines/js/package.json new file mode 100755 index 0000000..9592b54 --- /dev/null +++ b/environments/javascript/@orbitmines/js/package.json @@ -0,0 +1,36 @@ +{ + "name": "@orbitmines/js", + "version": "0.1.0", + "private": true, + "dependencies": { + "lodash": "^4.17.21" + }, + "devDependencies": { + "@types/jest": "^29.5.11", + "@types/lodash": "^4.14.194", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "typescript": "^5.0.4" + }, + "scripts": { + "test": "npx jest" + }, + "jest": { + "preset": "ts-jest", + "testMatch": [ + "**/*.spec.ts" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/orbitmines.com/src/@orbitmines/explorer/JS.spec.ts b/environments/javascript/@orbitmines/js/src/JS.spec.ts similarity index 84% rename from orbitmines.com/src/@orbitmines/explorer/JS.spec.ts rename to environments/javascript/@orbitmines/js/src/JS.spec.ts index 6b5eee0..39bc2c5 100644 --- a/orbitmines.com/src/@orbitmines/explorer/JS.spec.ts +++ b/environments/javascript/@orbitmines/js/src/JS.spec.ts @@ -1,72 +1,5 @@ -import Ray from "./Ray"; describe("JS", () => { - describe(".Function", () => { - describe(".Instance", () => { - - test(".traverse", () => { - const events: any[] = []; - const ray = Ray.New(); - - // const b = ray in ray; - - // ray()()()()(); - // - ray.debug( - (event) => { - events.push(event); - }, - () => { - try{ - ray.initial = new ray() - - } catch (e) {} - } - ); - - expect(events.map(event => ({ - event: event.event, context: event.context - }))).toBe(false); - - }); - test(".traverse", () => { - // const events: any[] = []; - // const ray = Ray.New(); - // - // ray.debug( - // (event) => { - // events.push(event); - // }, - // () => { - // // // Reference - // // ray.initial = none; - // // // ray.self = // SOMETHING - // // ray.terminal = none; - // // - // // // Initial - // // ray.initial = none; - // // ray.self = self_reference; - // // ray.terminal = self_reference; - // // - // // // Vertex: - // // ray.initial = self_reference; - // // ray.self = self_reference; - // // ray.terminal = self_reference; - // // - // // // Terminal - // // ray.initial = self_reference; - // // ray.self = self_reference; - // // ray.terminal = none; - // } - // ); - // - // expect(events.map(event => ({ - // event: event.event, context: { method: { property: event.context.method.property} } - // }))).toBe(false); - - }); - }) - }) // test(".Function.Ref(ref)", () => { // const method = Ray.Function.Ref((ref): Ray.Any => new Ray({ // initial: ref.self.initial.as_arbitrary(), diff --git a/orbitmines.com/src/@orbitmines/explorer/JS.ts b/environments/javascript/@orbitmines/js/src/JS.ts similarity index 93% rename from orbitmines.com/src/@orbitmines/explorer/JS.ts rename to environments/javascript/@orbitmines/js/src/JS.ts index 94cbee3..47fa618 100644 --- a/orbitmines.com/src/@orbitmines/explorer/JS.ts +++ b/environments/javascript/@orbitmines/js/src/JS.ts @@ -1,5 +1,4 @@ import _ from "lodash"; -import Ray from "./Ray"; /** * NOTE: @@ -37,7 +36,7 @@ namespace JS { export const Handler = (handler: JS.Class.Handler): ProxyHandler => ({ get: (___proxy_function: any, property: string | symbol, self: T): any => handler.get(self, ___proxy_function.___instance, property), - apply: (___proxy_function: any, thisArg: Ray.Any, argArray: any[]): any => handler.apply(thisArg ?? ___proxy_function.___instance.proxy, ___proxy_function.___instance, argArray), /** thisArg can be undefined. TODO: What's the use-case of us actually using it? */ + apply: (___proxy_function: any, thisArg: T, argArray: any[]): any => handler.apply(thisArg ?? ___proxy_function.___instance.proxy, ___proxy_function.___instance, argArray), /** thisArg can be undefined. TODO: What's the use-case of us actually using it? */ set: (___proxy_function: any, property: string | symbol, newValue: any, self: T): boolean => handler.set(self, ___proxy_function.___instance, property, newValue), deleteProperty: (___proxy_function: any, property: string | symbol): boolean => handler.deleteProperty(___proxy_function.___instance.proxy, ___proxy_function.___instance, property), has(___proxy_function: any, property: string | symbol): boolean { return handler.has(___proxy_function.___instance.proxy, ___proxy_function.___instance, property); }, diff --git a/orbitmines.com/src/@orbitmines/explorer/errors/errors.ts b/environments/javascript/@orbitmines/js/src/errors/errors.ts similarity index 100% rename from orbitmines.com/src/@orbitmines/explorer/errors/errors.ts rename to environments/javascript/@orbitmines/js/src/errors/errors.ts diff --git a/environments/javascript/@orbitmines/js/tsconfig.json b/environments/javascript/@orbitmines/js/tsconfig.json new file mode 100755 index 0000000..2fcde19 --- /dev/null +++ b/environments/javascript/@orbitmines/js/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ES2015", + "lib": ["esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "strictNullChecks": false, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "suppressImplicitAnyIndexErrors": false, + "noEmit": true, + "jsx": "react-jsx", + "emitDecoratorMetadata": true, + "experimentalDecorators": true + }, + "include": [ + "src" + ] +} \ No newline at end of file diff --git a/environments/javascript/@orbitmines/rays/index.ts b/environments/javascript/@orbitmines/rays/index.ts new file mode 100644 index 0000000..2397093 --- /dev/null +++ b/environments/javascript/@orbitmines/rays/index.ts @@ -0,0 +1,3 @@ +import Ray from './src/Ray'; + +export default Ray; \ No newline at end of file diff --git a/environments/javascript/@orbitmines/rays/package-lock.json b/environments/javascript/@orbitmines/rays/package-lock.json new file mode 100644 index 0000000..c14c3be --- /dev/null +++ b/environments/javascript/@orbitmines/rays/package-lock.json @@ -0,0 +1,4375 @@ +{ + "name": "@orbitmines/rays", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@orbitmines/rays", + "version": "0.1.0", + "dependencies": { + "@orbitmines/js": "file:../js" + }, + "devDependencies": { + "@types/jest": "^29.5.11", + "@types/node": "^20.1.0", + "jest": "^29.7.0", + "tree-sitter": "^0.20.6", + "tree-sitter-python": "^0.20.4", + "tree-sitter-typescript": "^0.20.3", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.2", + "typescript": "^5.0.4" + } + }, + "../js": { + "version": "0.1.0", + "dependencies": { + "lodash": "^4.17.21" + }, + "devDependencies": { + "@types/jest": "^29.5.11", + "@types/lodash": "^4.14.194", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "typescript": "^5.0.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", + "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@orbitmines/js": { + "resolved": "../js", + "link": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.11", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", + "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/node": { + "version": "20.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", + "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001580", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001580.tgz", + "integrity": "sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.645", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.645.tgz", + "integrity": "sha512-EeS1oQDCmnYsRDRy2zTeC336a/4LZ6WKqvSaM1jLocEk5ZuyszkQtCpsqvuvaIXGOUjwtvF6LTcS8WueibXvSw==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "dev": true + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-abi": { + "version": "3.54.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz", + "integrity": "sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tree-sitter": { + "version": "0.20.6", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.6.tgz", + "integrity": "sha512-GxJodajVpfgb3UREzzIbtA1hyRnTxVbWVXrbC6sk4xTMH5ERMBJk9HJNq4c8jOJeUaIOmLcwg+t6mez/PDvGqg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "nan": "^2.18.0", + "prebuild-install": "^7.1.1" + } + }, + "node_modules/tree-sitter-python": { + "version": "0.20.4", + "resolved": "https://registry.npmjs.org/tree-sitter-python/-/tree-sitter-python-0.20.4.tgz", + "integrity": "sha512-F+94q/t9+4J5yaQnmfAqEf4OZFjuhuyniRtb9P2jPaBwHrbyJL44RKFALovZxhF0syLFKpTQ7ODywyiGeB1YMg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "nan": "^2.17.0" + } + }, + "node_modules/tree-sitter-typescript": { + "version": "0.20.3", + "resolved": "https://registry.npmjs.org/tree-sitter-typescript/-/tree-sitter-typescript-0.20.3.tgz", + "integrity": "sha512-5+RZ9G3/VOxxSzyniVc5dfNhfan1eOxQvUdTgXhpsGIYlmSW3HwIuPEJ7r65FWH2WnJWirOu11Pm0usmkx2JOg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "nan": "^2.14.0" + } + }, + "node_modules/ts-jest": { + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", + "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/environments/javascript/@orbitmines/rays/package.json b/environments/javascript/@orbitmines/rays/package.json new file mode 100755 index 0000000..9b5b1ef --- /dev/null +++ b/environments/javascript/@orbitmines/rays/package.json @@ -0,0 +1,40 @@ +{ + "name": "@orbitmines/rays", + "version": "0.1.0", + "private": true, + "dependencies": { + "@orbitmines/js": "file:../js" + }, + "devDependencies": { + "@types/jest": "^29.5.11", + "@types/node": "^20.1.0", + "jest": "^29.7.0", + "tree-sitter": "^0.20.6", + "tree-sitter-python": "^0.20.4", + "tree-sitter-typescript": "^0.20.3", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.2", + "typescript": "^5.0.4" + }, + "scripts": { + "test": "npx jest" + }, + "jest": { + "preset": "ts-jest", + "testMatch": [ + "**/*.spec.ts" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/orbitmines.com/src/@orbitmines/explorer/Ray.spec.ts b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts similarity index 97% rename from orbitmines.com/src/@orbitmines/explorer/Ray.spec.ts rename to environments/javascript/@orbitmines/rays/src/Ray.spec.ts index 4af0c5e..98f11ff 100644 --- a/orbitmines.com/src/@orbitmines/explorer/Ray.spec.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts @@ -1,6 +1,95 @@ -import Ray, {Rays} from "./Ray"; +import Ray from "./Ray"; describe("Ray", () => { + + describe(".Function", () => { + describe(".Instance", () => { + + test(".traverse", () => { + const events: any[] = []; + const ray = Ray.New(); + + // const b = ray in ray; + + // ray()()()()(); + // + ray.debug( + (event) => { + events.push(event); + }, + () => { + try{ + ray.initial = new ray() + + } catch (e) {} + } + ); + + expect(events.map(event => ({ + event: event.event, context: event.context + }))).toBe(false); + + }); + test(".traverse", () => { + // const events: any[] = []; + // const ray = Ray.New(); + // + // ray.debug( + // (event) => { + // events.push(event); + // }, + // () => { + // // // Reference + // // ray.initial = none; + // // // ray.self = // SOMETHING + // // ray.terminal = none; + // // + // // // Initial + // // ray.initial = none; + // // ray.self = self_reference; + // // ray.terminal = self_reference; + // // + // // // Vertex: + // // ray.initial = self_reference; + // // ray.self = self_reference; + // // ray.terminal = self_reference; + // // + // // // Terminal + // // ray.initial = self_reference; + // // ray.self = self_reference; + // // ray.terminal = none; + // } + // ); + // + // expect(events.map(event => ({ + // event: event.event, context: { method: { property: event.context.method.property} } + // }))).toBe(false); + + }); + }) + }) + + + + + + + + + + + + + + + + + + + + + + // test(".is_orbit", () => { // const a = Ray.New(); // const b = Ray.New(); diff --git a/orbitmines.com/src/@orbitmines/explorer/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts similarity index 98% rename from orbitmines.com/src/@orbitmines/explorer/Ray.ts rename to environments/javascript/@orbitmines/rays/src/Ray.ts index 2dd4954..1ae5db5 100644 --- a/orbitmines.com/src/@orbitmines/explorer/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -1,6 +1,4 @@ -import JS from "./JS"; -import {NotImplementedError} from "./errors/errors"; - +import JS, {NotImplementedError} from "@orbitmines/js"; namespace Ray { @@ -26,9 +24,10 @@ namespace Ray { } export type Constructor = { - // initial?: Ray.FunctionConstructor, - // self?: Ray.FunctionConstructor, - // terminal?: Ray.FunctionConstructor, + initial?: Ray.Any, + self?: Ray.Any, + terminal?: Ray.Any, + proxy?: ProxyHandler, debug?: Debug.Listener, } @@ -249,7 +248,7 @@ namespace Ray { /** Implement a function from the perspective of 'this' */ export namespace Self { - export const Impl = (impl: Ray.Op.Unary | ((self: Ray.Any) => Ray.Any)): Ray.Any => { + export const Impl = (impl: Ray.Op.New | Ray.Op.Unary | ((self: Ray.Any) => Ray.Any)): Ray.Any => { throw new NotImplementedError(); // return new Ray.Any({ perspective: Perspective.Self, impl }); } @@ -345,7 +344,7 @@ namespace Ray { // @alias('destroy', 'clear', 'delete', 'pop') export const none = Ray.Function.Self.Impl( // TODO FROM REF SPEC? - self => self.self = Op.New.NONE // TODO self: self_reference + self => self.self //= Op.New.NONE // TODO self: self_reference ); /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ diff --git a/environments/javascript/@orbitmines/rays/tsconfig.json b/environments/javascript/@orbitmines/rays/tsconfig.json new file mode 100755 index 0000000..1941385 --- /dev/null +++ b/environments/javascript/@orbitmines/rays/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2015", + "lib": ["esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "strictNullChecks": false, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "suppressImplicitAnyIndexErrors": false, + "noEmit": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true + }, + "include": [ + "src" + ] +} \ No newline at end of file diff --git a/orbitmines.com/package-lock.json b/orbitmines.com/package-lock.json index b3fa804..38f9b14 100644 --- a/orbitmines.com/package-lock.json +++ b/orbitmines.com/package-lock.json @@ -1,17 +1,18 @@ { - "name": "@orbitmines/explorer-browser", + "name": "@orbitmines/orbitmines.com", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@orbitmines/explorer-browser", + "name": "@orbitmines/orbitmines.com", "version": "0.1.0", "dependencies": { "@blueprintjs/core": "^5.6.0", "@blueprintjs/docs-theme": "^5.2.2", "@blueprintjs/icons": "^5.4.0", "@blueprintjs/table": "^5.0.19", + "@orbitmines/rays": "file:../environments/javascript/@orbitmines/rays", "@react-pdf/renderer": "^3.1.9", "@react-three/drei": "^9.66.6", "@react-three/fiber": "^8.13.0", @@ -57,6 +58,24 @@ "typescript": "^5.0.4" } }, + "../environments/javascript/@orbitmines/rays": { + "version": "0.1.0", + "dependencies": { + "lodash": "^4.17.21" + }, + "devDependencies": { + "@types/jest": "^29.5.11", + "@types/lodash": "^4.14.194", + "@types/node": "^20.1.0", + "jest": "^29.7.0", + "tree-sitter": "^0.20.6", + "tree-sitter-python": "^0.20.4", + "tree-sitter-typescript": "^0.20.3", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.2", + "typescript": "^5.0.4" + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -4093,6 +4112,10 @@ "node": ">= 8" } }, + "node_modules/@orbitmines/rays": { + "resolved": "../environments/javascript/@orbitmines/rays", + "link": true + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.11", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz", diff --git a/orbitmines.com/package.json b/orbitmines.com/package.json index f2c9c7a..2fba579 100755 --- a/orbitmines.com/package.json +++ b/orbitmines.com/package.json @@ -1,5 +1,5 @@ { - "name": "@orbitmines/explorer-browser", + "name": "@orbitmines/orbitmines.com", "version": "0.1.0", "private": true, "dependencies": { @@ -7,6 +7,7 @@ "@blueprintjs/docs-theme": "^5.2.2", "@blueprintjs/icons": "^5.4.0", "@blueprintjs/table": "^5.0.19", + "@orbitmines/rays": "file:../environments/javascript/@orbitmines/rays", "@react-pdf/renderer": "^3.1.9", "@react-three/drei": "^9.66.6", "@react-three/fiber": "^8.13.0", @@ -58,8 +59,12 @@ "eject": "react-app-rewired eject" }, "jest": { - "testMatch": ["**/*.spec.ts"], - "testPathIgnorePatterns": [",./external"] + "testMatch": [ + "./**/*.spec.ts" + ], + "testPathIgnorePatterns": [ + ",./external" + ] }, "eslintConfig": { "extends": [ diff --git a/orbitmines.com/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/orbitmines.com/src/@orbitmines/explorer/debug/DebugCanvas.tsx index 80353a1..ad9345b 100644 --- a/orbitmines.com/src/@orbitmines/explorer/debug/DebugCanvas.tsx +++ b/orbitmines.com/src/@orbitmines/explorer/debug/DebugCanvas.tsx @@ -2,12 +2,12 @@ import IEventListener from "../../js/react/IEventListener"; import {VisualizationCanvas} from "../Visualization"; import React, {useEffect, useReducer, useRef, useState} from "react"; import {useHotkeys} from "../../js/react/hooks/useHotkeys"; -import {DebugResult, Ray, RayType} from "../Ray"; import {_Continuation, _Vertex, add, AutoVertex, circle, InterfaceOptions, Line, torus} from "../OrbitMinesExplorer"; import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; import {useThree} from "@react-three/fiber"; import {Stats, StatsGl} from "@react-three/drei"; import _ from "lodash"; +import Ray from "@orbitmines/rays" // TODO: What about showing disconnect when multiple things are rendered at the same position?? // TODO: It's, rende rboth draw equivalence, then ignore the difference from either perspective or take some middle thing. - Line from both ends, also vertex? (or take the pos, take the x from one/other, y from the other/..) diff --git a/orbitmines.com/src/@orbitmines/rays/index.ts b/orbitmines.com/src/@orbitmines/rays/index.ts deleted file mode 100644 index a4addde..0000000 --- a/orbitmines.com/src/@orbitmines/rays/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// import Ray from 'Ray'; -// TODO reexport as @orbitmines/rays From c477f137d5978cbc9bc914cf9842820b2b6cccce Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 18:57:51 +0100 Subject: [PATCH 124/138] 2024/01/25 - Move some files around, get tests working --- .../@orbitmines/rays/src/Ray.spec.ts | 9 +- .../javascript/@orbitmines/rays/src/Ray.ts | 41 ++++-- .../REFACTOR_AFTER_WORKING_TRAVERSE.md | 46 +------ orbitmines.com/useless_junk/generate_chyp.js | 130 ------------------ 4 files changed, 42 insertions(+), 184 deletions(-) delete mode 100644 orbitmines.com/useless_junk/generate_chyp.js diff --git a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts index 98f11ff..0c2d75f 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts @@ -1,4 +1,5 @@ import Ray from "./Ray"; +import rays from "../index"; describe("Ray", () => { @@ -19,7 +20,13 @@ describe("Ray", () => { }, () => { try{ - ray.initial = new ray() + if (ray) { + + } + // ray.initial = new ray(); + // ray.initial = ray.terminal(); + // ray.initial = (self): Ray.Any => {} + // ray.initial = Ray.Function.Self.Impl((self) => {}) } catch (e) {} } diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index 1ae5db5..600ff8c 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -117,6 +117,8 @@ namespace Ray { * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence * - a.orbit() -> a.orbit(a) * + * - .initial/.terminal can be seen as a particular connection on .self, which .self ignores? + * * TODO: Testing * - Test if references hold after equivalence/composition... * @@ -157,7 +159,7 @@ namespace Ray { if (func) { return func.as_method({ self, property }); } if (property === Symbol.toPrimitive) - return (hint: string) => { return 100; }; + return (hint: string) => { return 100; }; // TODO: Can be used to setup label generation through javascript objects if we want to ? + allow search on this // throw new NotImplementedError(``); /** Not implemented. */ @@ -207,24 +209,29 @@ namespace Ray { /** Ray is an Enum(eration) */ export namespace Enum { - export const Impl = >(...values: T): Enum => { + export const Impl = >(...values: T): Ray.Enum => { return Object.fromEntries(values.map(value => [value, Ray.Function.None.Impl((): Ray.Any => { throw new NotImplementedError(); // TODO })] - )) as Enum; + )) as Ray.Enum; // TODO: ONE OF 4 SELECTION RAY for the case of type. } } + /** Ray is a function (.next) */ export namespace Function { + // TODO: Reversible is orbit. + /** {T} is just an example/desired use case. But it generalizes to any function. */ export type Type = T | Ray.Any; /** From which perspective the Function is implemented. */ - enum Perspective { None, Self, /** Ref, */ } // TODO Ray.Enum? or not. + enum Perspective { + None, Self, /** Ref, */ + } // TODO Ray.Enum? or not. // /** // * Implement a function from the perspective of 'this' for 'this.self'. @@ -277,7 +284,13 @@ namespace Ray { return Impl(self => self); // TODO } } + } + /** TODO: Shouldn't classify these? */ + export const Type = Ray.Enum.Impl('REFERENCE', 'INITIAL', 'TERMINAL', 'VERTEX'); + + + export namespace Function { export const Get = ( property: TProperty ): (typeof Ray.Function.All)[TProperty] | undefined => Ray.Function.All[property as TProperty] ?? undefined; @@ -461,6 +474,22 @@ namespace Ray { export const push_front = Ray.Function.Self.Binary( (a, b) => b.compose(a.first()) ); + + /** + * Performing a copy (realizing it) can be conceptualized as traversing the entire structure. (Where the 'entire structure' means the current instantiation of it - with many ignorances attached) + * + * - A problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. + * - This copy does not do that. Instead, it is ignorant of other things referencing the thing it's copying. + * - Additionally, a copy necessarily has some non-redundancy to it: + * + * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy + */ + // @alias('clone', 'duplicate') + export const copy = Ray.Function.Self.Impl( + (self) => none().self = self.self.copy() // TODO Relies heavily on the execution layer to copy initial/terminal etc... ; and an is_orbit check before calling copy again. - Then again on the execution layer it can lazily do this copy (by not evaluating (i.e.) traversing everywhere), or it first does this traversing directly. + ); + + } } @@ -474,10 +503,6 @@ namespace Ray { export const number = (number: number) => { throw new NotImplementedError(); } - - /** TODO: Shouldn't classify these? */ - export const Type = Ray.Enum.Impl('REFERENCE', 'INITIAL', 'TERMINAL', 'VERTEX'); - // export const Boundary = { INITIAL: Type.INITIAL, TERMINAL: Type.TERMINAL }; TODO: LIST O // TODO CAN ALSO BE ZERO-ARY.. diff --git a/orbitmines.com/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md b/orbitmines.com/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md index 7dcdcb1..dc1151b 100644 --- a/orbitmines.com/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md +++ b/orbitmines.com/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md @@ -2,37 +2,9 @@ // NOT NEEDED FOR INITIAL DEMONSTRATION: ```ts - // TODO; Could return the ignorant reference to both instances, or just the result., .. - -/** - * - The problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. - * - * - Additionally, a copy necessarily has some non-redundancy to it: - * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy - */ -// @alias('duplicate') -copy = (): Ray.Any => { - // return this.self.as_reference(); // Copies the reference? - throw new NotImplementedError(); - - // const copy = new Ray({ - // initial: this.self._initial().as_reference().none_or(ref => ref.copy()).as_arbitrary(), - // vertex: this.self._vertex().as_reference().none_or(ref => ref.copy()).as_arbitrary(), - // }).o({ ___dirty_copy_buffer: {} }); - // // copy._initial = () => copy.any.___dirty_copy_buffer._initial ??= this.self._initial().as_reference().copy(); - // // copy._vertex = () => copy.any.___dirty_copy_buffer._vertex ??= this.self._vertex().as_reference().copy(); - // // copy._terminal = () => copy.any.___dirty_copy_buffer._terminal ??= this.self._terminal().as_reference().copy(); - // - // - // // TODO: Doesn't copy .any - // - // return copy.as_reference(); -} - get count(): Ray.Any { return JS.Number(this.as_array().length); } - - + // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. ; each individually, again, additional structure... // TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? @@ -43,7 +15,6 @@ is_vertex_equivalent = (b: Ray.Any) => { // none_or = (arbitrary: Implementation): Ray.Any => this.is_none() ? Ray.None() : arbitrary(this); - /** * https://en.wikipedia.org/wiki/Homoiconicity */ @@ -73,21 +44,6 @@ static zip = Ray.Function.Impl((initial, terminal) => { }); zip = Ray.zip.as_method(this); -/** - * TODO: This should be constructed at the vertex and in general unsolvable - * - * TODO: Setup labels - * TODO: Use JavaScript engine for generating these for a default impl without someone supplying their own gen func?? - * TODO: + allow for searching/doing stuff based on some label ; this can be arbitrarily through the structure - */ -static _label: number = 0; -get label(): string { - if (this.any.label !== undefined) - return this.any.label; - - return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; -} - /** * Used for chaining JavaScript-provided properties * diff --git a/orbitmines.com/useless_junk/generate_chyp.js b/orbitmines.com/useless_junk/generate_chyp.js deleted file mode 100644 index d99736b..0000000 --- a/orbitmines.com/useless_junk/generate_chyp.js +++ /dev/null @@ -1,130 +0,0 @@ -const Parser = require('tree-sitter'); -const TypeScript = require('tree-sitter-typescript'); -const Python = require('tree-sitter-python'); -const fs = require("fs"); -const path = require('path'); -const _ = require("lodash"); - -const parser = new Parser(); -parser.setLanguage(Python); - -function getAllFilesSync(dir, fileList = []) { - const files = fs.readdirSync(dir); - - for (const file of files) { - const filePath = path.join(dir, file); - const stat = fs.statSync(filePath); - - if (stat.isDirectory()) { - getAllFilesSync(filePath, fileList); - } else { - if (path.extname(file) === '.py') { - fileList.push(filePath); - } - } - } - - return fileList; -} - -const files = getAllFilesSync("../src/@orbitmines/external/github.com/akissinger/chyp/chyp"); -console.log(files) - - -const classesAndMethods = []; - - -files.forEach(file => { - const source = fs.readFileSync(file, 'utf-8') - const tree = parser.parse(source); -// Traverse the AST to extract classes, methods, arguments, and return types - - tree.rootNode.children.forEach((node) => { - if (node.type === 'class_definition') { - const currentClass = { - name: node.firstChild.nextNamedSibling.text, - methods: [], - }; - - // Traverse class body for methods - node.lastChild.children.forEach((classChildNode) => { - if (classChildNode.type === 'function_definition') { - const method = { - name: classChildNode.firstChild.nextNamedSibling.text, - arguments: [], - returnType: 'any', // Default return type - }; - - // Traverse method parameters - classChildNode.firstChild.nextNamedSibling.nextSibling.children.forEach((paramNode) => { - - if (paramNode.type === 'typed_parameter') { - const paramName = paramNode.firstChild.text; - const paramTypeNode = paramNode.lastChild; - - // console.log(paramTypeNode.text) - - // Check if there is a type annotation - const paramType = paramTypeNode.text ?? 'any'; - - method.arguments.push({ name: paramName, type: paramType }); - } - }); - - // Check for return type annotation - const returnTypeNode = classChildNode.lastChild.firstChild; - if (returnTypeNode && returnTypeNode.type === 'typed_identifier') { - method.returnType = returnTypeNode.lastChild.text; - } - - currentClass.methods.push(method); - } - }); - - classesAndMethods.push(currentClass); - } - }); -}) -// Print the extracted information -console.log(JSON.stringify(classesAndMethods, null, 2)); - -function generateTypeScriptTypes(classesAndMethods) { - const typeScriptCode = []; - - classesAndMethods.forEach((classInfo) => { - typeScriptCode.push(`export class ${classInfo.name} extends Ray {`); - - classInfo.methods.forEach((method) => { - const params = method.arguments.map((arg) => `${arg.name}: ${ - _.last(arg.type - .replaceAll('[', '<') - .replaceAll(']', '>') - .replaceAll(/<(.*)>,/g, "$1[],") - .split('.')) - }`).join(', '); - typeScriptCode.push(` ${method.name} = (${params}): ${method.returnType} => { throw new NotImplementedError(); }`); - }); - - typeScriptCode.push('}\n'); - }); - - return typeScriptCode.join('\n'); -} - -// Assuming classesAndMethods is the result from the previous script -const typeScriptCode = ` -${_.uniq(classesAndMethods.flatMap(c => c.methods).flatMap(method => [method.returnType, ...method.arguments.map(arg => arg.type)]) - .flatMap(arg => arg.split(/[\[\],.|]/g)) - .map(arg => arg.trim()) - .filter(arg => arg !== '') -) - .filter(arg => arg !== 'any' && !classesAndMethods.map(c => c.name).includes(arg)) - .map(arg => `export type ${ - arg - } = any;`).join('\n')} - -${generateTypeScriptTypes(classesAndMethods)} -`; - - -fs.writeFileSync('../src/@orbitmines/external/implementations/chyp/Chyp_naieve_pass.ts', typeScriptCode) \ No newline at end of file From 5dfdef73cdfefc2be45e9a401742c8f65732b72f Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 21:58:38 +0100 Subject: [PATCH 125/138] 2024/01/25 - Ops, docs --- .../@orbitmines/rays/src/Ray.spec.ts | 5 +- .../javascript/@orbitmines/rays/src/Ray.ts | 213 ++++++++++-------- .../src/@orbitmines/explorer/Ray2.ts | 7 - 3 files changed, 117 insertions(+), 108 deletions(-) diff --git a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts index 0c2d75f..ef31c3b 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts @@ -8,7 +8,7 @@ describe("Ray", () => { test(".traverse", () => { const events: any[] = []; - const ray = Ray.New(); + const ray = Ray.array([]); // const b = ray in ray; @@ -21,8 +21,11 @@ describe("Ray", () => { () => { try{ if (ray) { + ray.is_orbit(); } + new ray.initial; + // ray.initial = new ray(); // ray.initial = ray.terminal(); // ray.initial = (self): Ray.Any => {} diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index 600ff8c..9cf9db8 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -17,12 +17,16 @@ namespace Ray { & Pick + /** Preconfigured functions defined for Rays. */ & { -readonly [TKey in keyof typeof Ray.Function.All]: typeof Ray.Function.All[TKey] extends Ray.Any ? Ray.Any : never; } + /** Storage/Movement operations which need to be implemented. */ + & { [TKey in keyof Ray.Op.Impl]: Ray.Any } + export type Constructor = { initial?: Ray.Any, self?: Ray.Any, @@ -39,14 +43,6 @@ namespace Ray { export type Listener = (event: Event) => void; } - export type Op = { get: (self: Ray.Any) => Ray.Any, set: (self: Ray.Any) => Ray.Any }; - // export type Ops = { - // initial(self: Ray.Any): Ray.Any; - // self(self: Ray.Any): Ray.Any; - // terminal(self: Ray.Any): Ray.Any; - // is_orbit(a: Ray.Any, b: Ray.Any): boolean; - // } - /** * An uninitialized empty Ray, which caches itself once initialized. */ @@ -116,6 +112,7 @@ namespace Ray { * - None as, first time called, memoize func. * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence * - a.orbit() -> a.orbit(a) + * // TODO: Should be automatic? is_orbit() or any method without arguments is a.is_orbit(a.self()) ?? not a.is_orbit(a) ; ??? * * - .initial/.terminal can be seen as a particular connection on .self, which .self ignores? * @@ -128,22 +125,6 @@ namespace Ray { } - export namespace Op { - export enum New { NONE, INITIAL, VERTEX, TERMINAL } - export enum Zeroary { - - } - // Should not need anything elese ; so could be any one thing? - export enum Unary { - INITIAL, - SELF, // TODO .as_reference? Basically, Ray.directions - TERMINAL - } - export enum Binary { - IS_ORBIT // a.___instance === b.___instance - } - } - export namespace ProxyHandlers { export const Default: ProxyHandler = JS.Class.Handler({ @@ -203,18 +184,19 @@ namespace Ray { }); } - export type Enum> = { - [TKey in T[number]]: Ray.Any - } /** Ray is an Enum(eration) */ export namespace Enum { - export const Impl = >(...values: T): Ray.Enum => { - return Object.fromEntries(values.map(value => + export type Type> = { + [TKey in T[number]]: Ray.Any + } + + export const Impl = >(...enumeration: T): Type => { + return Object.fromEntries(enumeration.map(value => [value, Ray.Function.None.Impl((): Ray.Any => { throw new NotImplementedError(); // TODO })] - )) as Ray.Enum; + )) as Type; // TODO: ONE OF 4 SELECTION RAY for the case of type. } @@ -223,30 +205,23 @@ namespace Ray { /** Ray is a function (.next) */ export namespace Function { - // TODO: Reversible is orbit. - /** {T} is just an example/desired use case. But it generalizes to any function. */ export type Type = T | Ray.Any; /** From which perspective the Function is implemented. */ enum Perspective { None, Self, /** Ref, */ - } // TODO Ray.Enum? or not. + } // /** // * Implement a function from the perspective of 'this' for 'this.self'. // */ // // static Ref = (impl: (ref: Ray.Any) => TResult): Function => Ray.Function.Self(self => impl(self.as_reference())); - // // static CachedAfterUse = (constructor: FunctionConstructor): FunctionConstructor => { - // // return constructor; - // // } - - /** Implement a function from no (or: an ignorant) perspective. */ export namespace None { - export const Impl = (impl: () => Ray.Any): Ray.Any => { + export const Impl = (impl: Op.Zeroary.Type): Ray.Any => { throw new NotImplementedError(); // return new Ray.Any({ perspective: Perspective.None, impl }); } @@ -255,40 +230,98 @@ namespace Ray { /** Implement a function from the perspective of 'this' */ export namespace Self { - export const Impl = (impl: Ray.Op.New | Ray.Op.Unary | ((self: Ray.Any) => Ray.Any)): Ray.Any => { + export const Impl = (impl: Op.Unary.Type): Ray.Any => { throw new NotImplementedError(); // return new Ray.Any({ perspective: Perspective.Self, impl }); } - export const Binary = (impl: Ray.Op.Binary | ((a: Ray.Any, b: Ray.Any) => Ray.Any)): Ray.Any => { + export const Binary = (impl: Op.Binary.Type): Ray.Any => { throw new NotImplementedError(); // return new Ray.Any({ perspective: Perspective.Self, impl }); // TODO: Good way to deal with arity } - export const If = (impl: (self: Ray.Any) => Ray.Any): Ray.Any => { - return Impl(impl); // TODO: GENERIC collapse to boolean implemented and overridable - } - - export type MatchCase = [ - Function.Type, - Function.Type - ]; - - export type MatchCases = [...MatchCase[], /** 'else, ... default' **/ Function.Type]; + // export const If = (impl: Op.Unary.Type): Ray.Any => { + // return Impl(impl); // TODO: GENERIC collapse to boolean implemented and overridable + // } + // TODO: GENERIC collapse to boolean implemented and overridable /** * TODO: * - Maybe replace switch with 'zip'?, What are the practical differences? */ - export const Match = (cases: MatchCases): Ray.Any => { - return Impl(self => self); // TODO - } + // export const Match = (cases: MatchCases): Ray.Any => { + // return Impl(self => self); // TODO + // } } } - /** TODO: Shouldn't classify these? */ - export const Type = Ray.Enum.Impl('REFERENCE', 'INITIAL', 'TERMINAL', 'VERTEX'); + export namespace Op { + + export type Impl = + { [TKey in keyof (typeof Op.Zeroary.All)]: Op.Zeroary.Type } + & { [TKey in keyof (typeof Op.Unary.All)]: Op.Unary.Type } + & { [TKey in keyof (typeof Op.Binary.All)]: Op.Binary.Type } + + export const all = (ops: TOps): { + [TOP in keyof TOps]: Ray.Any + } => ({}); + + export namespace Zeroary { + export type Type = () => T; + export type Any = (keyof typeof Op.Zeroary.All) | Type; + // TODO: set = none; + // TODO: Destroy the current thing, connect .initial & .terminal ? (can do just direct connection, preserves 'could have been something here') - then something like [self.initial, self, self.terminal].pop(). + // TODO: Leave behind --] [-- or connect them basically.. + export const All = Op.all({ + // @alias('alloc', 'new', 'create', 'initialize') + none: 'none', + // @alias('free', 'destroy', 'clear', 'delete', 'pop') + free: 'free', + }); + } + export namespace Unary { + export type Type = (a: T) => T; + export type Any = (keyof typeof Op.Unary.All) | Type; + + export const All = Op.all({ + + /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ + initial: 'initial', // a.initial + + /** + * An arbitrary Ray, defining what our current position is equivalent to. + * + * Moving to the intersecting Ray at `.self` - as a way of going an abstraction layer (lower), and asking what's inside. + */ + // @alias('dereference', 'self') + self: 'self', // a.self + + /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ + terminal: 'terminal', // a.terminal + }); + } + export namespace Binary { + export type Type = (a: T, b: T) => T; + export type Any = (keyof typeof Op.Binary.All) | Type; + + export const All = Op.all({ + initial: 'initial', // a.initial = b + self: 'self', // a.self = b + terminal: 'terminal', // a.terminal = b + + /** + * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. + */ + // @alias('is_none') + is_orbit: 'is_orbit', // a.___instance === b.___instance + }); + } + } export namespace Function { export const Get = ( @@ -313,13 +346,6 @@ namespace Ray { self => self.is_initial().xor(self.is_terminal()) ); - export const type = Ray.Function.Self.Match([ - /** [ | ] */ [is_reference, Ray.Type.REFERENCE], - /** [ |-?] */ [is_initial, Ray.Type.INITIAL], - /** [?-| ] */ [is_terminal, Ray.Type.TERMINAL], - /** [--|--] */ Ray.Type.VERTEX - ]); - /** * This is basically what breaks the recursive structure. * @@ -333,53 +359,22 @@ namespace Ray { * * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. */ - export const is_none = Ray.Function.Self.Impl( - self => self.is_orbit(self.dereference()) - ); + export const is_none = Ray.Op.Binary.All.is_orbit; export const is_some = Ray.Function.Self.Impl( self => self.is_none().not() ); - /** - * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. - * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. - */ - export const is_orbit = Ray.Function.Self.Binary(Op.Binary.IS_ORBIT); - export const self_reference = Ray.Function.Self.Impl( self => self ); - // TODO: set = none; - // TODO: Destroy the current thing, connect .initial & .terminal ? (can do just direct connection, preserves 'could have been something here') - then something like [self.initial, self, self.terminal].pop(). - // TODO: Leave behind --] [-- or connect them basically.. - - // @alias('destroy', 'clear', 'delete', 'pop') - export const none = Ray.Function.Self.Impl( // TODO FROM REF SPEC? - self => self.self //= Op.New.NONE // TODO self: self_reference - ); - - /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ - export const terminal = Ray.Function.Self.Impl(Op.Unary.TERMINAL); - /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ - export const initial = Ray.Function.Self.Impl(Op.Unary.INITIAL); - /** - * An arbitrary Ray, defining what our current position is equivalent to. - * - * Moving to the intersecting Ray at `.self` - as a way of going an abstraction layer (lower), and asking what's inside. - */ - // @alias('dereference', 'self') - export const dereference = Ray.Function.Self.Impl(Op.Unary.SELF); - export const self = dereference; - /** * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. * * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) */ export const reference = Ray.Function.Self.Impl( - self => Ray.New({ self: self }) + self => Ray.Op.Zeroary.All.none().self = self ); /** @@ -390,7 +385,14 @@ namespace Ray { (a, b) => a.terminal().equivalent(b.initial()) ); - // @alias('modular', 'modulus', 'orbit') + /** + * - TODO: Note that an orbit is reversibility. ? + * + * - Like with 'copy' and all concepts: Note that we're only after reversibility after ignoring some difference. + * + * @see "Reversibility is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Another%20example%20of%20this%20is%20reversibility + */ + // @alias('modular', 'modulus', 'orbit', 'circle', 'repeats', 'infinitely') export const orbit = Ray.Function.Self.Binary( (a, b) => a.first().initial().compose(b.last().terminal()) ); @@ -414,11 +416,17 @@ namespace Ray { }); /** - * If there exists an orbit between A & B, anywhere (so dually connected, what if only one is aware??). + * If there exists an orbit between A & B anywhere on their equivalency functions - or: their .self - (except for the directions through which we're referencing them) + * + * Note the connection between 'is_orbit' vs 'is_equivalence'. They're essentially the same thing, but: + * - in the case of 'is_equivalence' we directly have access to their difference but are explicitly ignoring them - in the context in which this functionality is called. + * - in the case of 'is_orbit', we might need to do more complicated things to acknowledge their differences - we don't have direct access to them. + * + * TODO: (so dually connected, what if only one is aware??) Or basically just ; the answer in this particular instance is just if either end can find the other only once. Consistency of it defined on a more abstract level... */ // @alias('includes', 'contains') ; (slightly different variants?) export const is_equivalent = Ray.Function.Self.Binary( - (a, b) => a.self().traverse().is_orbit(b.self().traverse()) // Basically: does there exist a single connection between the two? + (a, b) => a.traverse().is_orbit(b.traverse()) // Basically: does there exist a single connection between the two? ); export const traverse = Ray.Function.Self.Impl( @@ -486,7 +494,11 @@ namespace Ray { */ // @alias('clone', 'duplicate') export const copy = Ray.Function.Self.Impl( - (self) => none().self = self.self.copy() // TODO Relies heavily on the execution layer to copy initial/terminal etc... ; and an is_orbit check before calling copy again. - Then again on the execution layer it can lazily do this copy (by not evaluating (i.e.) traversing everywhere), or it first does this traversing directly. + // or + // (self) => self.self.copy.reference() + (self) => Ray.Op.Zeroary.All.none().self = self.self.copy() + + // TODO Relies heavily on the execution layer to copy initial/terminal etc... ; and an is_orbit check before calling copy again. - Then again on the execution layer it can lazily do this copy (by not evaluating (i.e.) traversing everywhere), or it first does this traversing directly. ); @@ -494,6 +506,7 @@ namespace Ray { } /** JavaScript runtime conversions */ + export const array = (array: T[]): Ray.Any => Ray.iterable(array); export const iterable = (iterable: Iterable): Ray.Any => Ray.iterator(iterable[Symbol.iterator]()); export const async_iterable = (async_iterable: AsyncIterable): Ray.Any => Ray.async_iterator(async_iterable[Symbol.asyncIterator]()); export const iterator = (iterator: Iterator): Ray.Any => { throw new NotImplementedError(); } diff --git a/orbitmines.com/src/@orbitmines/explorer/Ray2.ts b/orbitmines.com/src/@orbitmines/explorer/Ray2.ts index 6b56115..7739a75 100644 --- a/orbitmines.com/src/@orbitmines/explorer/Ray2.ts +++ b/orbitmines.com/src/@orbitmines/explorer/Ray2.ts @@ -185,13 +185,6 @@ export class Ray { equivalent = Ray.equivalent.as_method(this); - - - static follow_direction = { - [RayType.INITIAL]: Ray.Any.directions.next, - [RayType.TERMINAL]: Ray.Any.directions.previous - } - /** * .next */ From a150f67b02daaa6292746a8148017697fe566499 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 22:12:32 +0100 Subject: [PATCH 126/138] 2024/01/25 - Minor doc/impl changes --- environments/javascript/@orbitmines/rays/src/Ray.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index 9cf9db8..8e37126 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -116,6 +116,8 @@ namespace Ray { * * - .initial/.terminal can be seen as a particular connection on .self, which .self ignores? * + * TODO: Allow hooking + * * TODO: Testing * - Test if references hold after equivalence/composition... * @@ -386,7 +388,9 @@ namespace Ray { ); /** + * "Composing an terminal & initial boundary" * - TODO: Note that an orbit is reversibility. ? + * - TODO: Could represent this abstraction in another layer what we want to accomplish while the actual search is still taking place. * * - Like with 'copy' and all concepts: Note that we're only after reversibility after ignoring some difference. * @@ -394,7 +398,7 @@ namespace Ray { */ // @alias('modular', 'modulus', 'orbit', 'circle', 'repeats', 'infinitely') export const orbit = Ray.Function.Self.Binary( - (a, b) => a.first().initial().compose(b.last().terminal()) + (a, b) => b.last().compose(a.first()) ); /** @@ -426,7 +430,7 @@ namespace Ray { */ // @alias('includes', 'contains') ; (slightly different variants?) export const is_equivalent = Ray.Function.Self.Binary( - (a, b) => a.traverse().is_orbit(b.traverse()) // Basically: does there exist a single connection between the two? + (a, b) => a.self().traverse().is_orbit(b.self().traverse()) // Basically: does there exist a single connection between the two? ); export const traverse = Ray.Function.Self.Impl( From 66b8249f1fc831b80b3bfa64461364f4b3ed9cf1 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 22:22:42 +0100 Subject: [PATCH 127/138] 2024/01/25 - Minor doc/impl changes --- .../javascript/@orbitmines/rays/src/Ray.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index 8e37126..b77cf1e 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -99,6 +99,8 @@ namespace Ray { export class Compiler { // Ray is Compiler /** + * TODO: Do I want to keep the is_equiv/is_composed pattern? Or simplify to one of the two? + * * // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY * * TODO @@ -280,8 +282,6 @@ namespace Ray { export const All = Op.all({ // @alias('alloc', 'new', 'create', 'initialize') none: 'none', - // @alias('free', 'destroy', 'clear', 'delete', 'pop') - free: 'free', }); } export namespace Unary { @@ -290,6 +290,9 @@ namespace Ray { export const All = Op.all({ + // @alias('free', 'destroy', 'clear', 'delete', 'pop') + free: 'free', + /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ initial: 'initial', // a.initial @@ -398,7 +401,11 @@ namespace Ray { */ // @alias('modular', 'modulus', 'orbit', 'circle', 'repeats', 'infinitely') export const orbit = Ray.Function.Self.Binary( - (a, b) => b.last().compose(a.first()) + /** + * - TODO: If we're only doing one end: This already assumes they are connected on the other end. + * - TODO: should be a connection here, with is_composed ; or "reference.is_equivalent" so that you can drop one of the sides, or both. + */ + (a, b) => ( b.last().compose(a.first()) ).and( a.first().compose(b.last()) ) ); /** @@ -430,8 +437,12 @@ namespace Ray { */ // @alias('includes', 'contains') ; (slightly different variants?) export const is_equivalent = Ray.Function.Self.Binary( - (a, b) => a.self().traverse().is_orbit(b.self().traverse()) // Basically: does there exist a single connection between the two? + (a, b) => a.self().traverse().is_orbit(b.self().traverse()) ); + // TODO: Either is_equiv or is_composed will likely change?. + export const is_composed = Ray.Function.Self.Binary( + (a, b) => a.traverse().is_orbit(b.traverse()) // Basically: does there exist a single connection between the two? + ); export const traverse = Ray.Function.Self.Impl( (a) => { throw new NotImplementedError(); } From 8b8769f18ae67b45e22f77e293f7deedd01fcd3c Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 22:34:22 +0100 Subject: [PATCH 128/138] 2024/01/25 - as_(reference, vertex, terminal, initial) --- .../@orbitmines/rays/src/Ray.spec.ts | 36 ------------- .../javascript/@orbitmines/rays/src/Ray.ts | 50 +++++++++++++++---- 2 files changed, 40 insertions(+), 46 deletions(-) diff --git a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts index ef31c3b..c0404f0 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts @@ -40,42 +40,6 @@ describe("Ray", () => { }))).toBe(false); }); - test(".traverse", () => { - // const events: any[] = []; - // const ray = Ray.New(); - // - // ray.debug( - // (event) => { - // events.push(event); - // }, - // () => { - // // // Reference - // // ray.initial = none; - // // // ray.self = // SOMETHING - // // ray.terminal = none; - // // - // // // Initial - // // ray.initial = none; - // // ray.self = self_reference; - // // ray.terminal = self_reference; - // // - // // // Vertex: - // // ray.initial = self_reference; - // // ray.self = self_reference; - // // ray.terminal = self_reference; - // // - // // // Terminal - // // ray.initial = self_reference; - // // ray.self = self_reference; - // // ray.terminal = none; - // } - // ); - // - // expect(events.map(event => ({ - // event: event.event, context: { method: { property: event.context.method.property} } - // }))).toBe(false); - - }); }) }) diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index b77cf1e..6221820 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -99,6 +99,9 @@ namespace Ray { export class Compiler { // Ray is Compiler /** + * TODO: Compiler could have things like other composed rays which tell it cares about the other (even if that's correct or not??) + * + * * TODO: Do I want to keep the is_equiv/is_composed pattern? Or simplify to one of the two? * * // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY @@ -373,15 +376,6 @@ namespace Ray { self => self ); - /** - * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. - * - * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) - */ - export const reference = Ray.Function.Self.Impl( - self => Ray.Op.Zeroary.All.none().self = self - ); - /** * @see "Continuations as Equivalence (can often be done in parallel - not generally)": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence */ @@ -511,11 +505,47 @@ namespace Ray { export const copy = Ray.Function.Self.Impl( // or // (self) => self.self.copy.reference() - (self) => Ray.Op.Zeroary.All.none().self = self.self.copy() + (self) => none().self = self.self.copy() // TODO Relies heavily on the execution layer to copy initial/terminal etc... ; and an is_orbit check before calling copy again. - Then again on the execution layer it can lazily do this copy (by not evaluating (i.e.) traversing everywhere), or it first does this traversing directly. ); + export const none = Ray.Op.Zeroary.All.none; // TODO FOR ALL OPS, ? automatic, or just put them here. + + // TODO: These should allow as_vertex as zero-ary, but that means self = self_reference, not none. ? + /** + * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. + * + * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) + */ + export const as_reference = Ray.Function.Self.Impl( + self => none().self = self + ); + + export const as_vertex = Ray.Function.Self.Impl((self) => { + const vertex = Ray.Op.Zeroary.All.none(); + vertex.initial = self_reference; + vertex.terminal = self_reference; + vertex.self = self; // TODO: Like this, ignorant vs non-ignorant? What to do here? + + return vertex; + }); + export const as_terminal = Ray.Function.Self.Impl((self) => { + const terminal = Ray.Op.Zeroary.All.none(); + terminal.initial = self_reference; + // terminal.terminal = none; + terminal.self = self; + + return terminal; + }); + export const as_initial = Ray.Function.Self.Impl((self) => { + const initial = Ray.Op.Zeroary.All.none(); + // initial.initial = none; + initial.terminal = self_reference; + initial.self = self; + + return initial; + }); } } From 84b11c357d2b26744c0f2566482e7d60e09c9a6f Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Thu, 25 Jan 2024 22:35:16 +0100 Subject: [PATCH 129/138] 2024/01/25 - as_(reference, vertex, terminal, initial) --- .../javascript/@orbitmines/rays/src/Ray.ts | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index 6221820..cb820af 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -512,40 +512,43 @@ namespace Ray { export const none = Ray.Op.Zeroary.All.none; // TODO FOR ALL OPS, ? automatic, or just put them here. - // TODO: These should allow as_vertex as zero-ary, but that means self = self_reference, not none. ? /** - * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. - * - * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) + * Placing existing structure on a new Reference, Boundary or Vertex: */ - export const as_reference = Ray.Function.Self.Impl( - self => none().self = self - ); + // TODO: These should allow as_vertex as zero-ary, but that means self = self_reference, not none. ? + /** + * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. + * + * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) + */ + export const as_reference = Ray.Function.Self.Impl( + self => none().self = self + ); - export const as_vertex = Ray.Function.Self.Impl((self) => { - const vertex = Ray.Op.Zeroary.All.none(); - vertex.initial = self_reference; - vertex.terminal = self_reference; - vertex.self = self; // TODO: Like this, ignorant vs non-ignorant? What to do here? + export const as_vertex = Ray.Function.Self.Impl((self) => { + const vertex = Ray.Op.Zeroary.All.none(); + vertex.initial = self_reference; + vertex.terminal = self_reference; + vertex.self = self; // TODO: Like this, ignorant vs non-ignorant? What to do here? - return vertex; - }); - export const as_terminal = Ray.Function.Self.Impl((self) => { - const terminal = Ray.Op.Zeroary.All.none(); - terminal.initial = self_reference; - // terminal.terminal = none; - terminal.self = self; + return vertex; + }); + export const as_terminal = Ray.Function.Self.Impl((self) => { + const terminal = Ray.Op.Zeroary.All.none(); + terminal.initial = self_reference; + // terminal.terminal = none; + terminal.self = self; - return terminal; - }); - export const as_initial = Ray.Function.Self.Impl((self) => { - const initial = Ray.Op.Zeroary.All.none(); - // initial.initial = none; - initial.terminal = self_reference; - initial.self = self; + return terminal; + }); + export const as_initial = Ray.Function.Self.Impl((self) => { + const initial = Ray.Op.Zeroary.All.none(); + // initial.initial = none; + initial.terminal = self_reference; + initial.self = self; - return initial; - }); + return initial; + }); } } From 63b939b12b136ffb53009b73611aba31e1c939e4 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 29 Jan 2024 15:54:59 +0100 Subject: [PATCH 130/138] 2024/01/29 - Some thinking on runtime/compiler differences --- .../@orbitmines/rays/src/Ray.spec.ts | 22 ++- .../javascript/@orbitmines/rays/src/Ray.ts | 151 ++++++++++-------- .../src/@orbitmines/explorer/Ray2.ts | 17 -- 3 files changed, 101 insertions(+), 89 deletions(-) diff --git a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts index c0404f0..6e1fa09 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts @@ -1,11 +1,29 @@ import Ray from "./Ray"; -import rays from "../index"; describe("Ray", () => { describe(".Function", () => { describe(".Instance", () => { + test(".te", () => { + { + // "new Ray.vertex()()" vs "new Ray.vertex()" + const A = new Ray.vertex(); + const B = new Ray.vertex(); + A.compose(B); + } + { + const ray = Ray.size(2); + } + { + const ray = Ray.array([undefined, undefined]); + + } + { + const ray = Ray.boolean(); + } + + }); test(".traverse", () => { const events: any[] = []; const ray = Ray.array([]); @@ -15,7 +33,7 @@ describe("Ray", () => { // ray()()()()(); // ray.debug( - (event) => { + (event: Ray.Debug.Event) => { events.push(event); }, () => { diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index cb820af..6edc32d 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -27,17 +27,6 @@ namespace Ray { /** Storage/Movement operations which need to be implemented. */ & { [TKey in keyof Ray.Op.Impl]: Ray.Any } - export type Constructor = { - initial?: Ray.Any, - self?: Ray.Any, - terminal?: Ray.Any, - - proxy?: ProxyHandler, - debug?: Debug.Listener, - } - - export const New = (constructor?: Ray.Constructor): Ray.Any => Ray.Instance.New(constructor).proxy; - export namespace Debug { export type Event = { event: string, self: Ray.Any, context: any }; export type Listener = (event: Event) => void; @@ -48,29 +37,72 @@ namespace Ray { */ // export const None: Ray.FunctionConstructor = Ray.Function.CachedAfterUse(Ray.New); - export class Instance extends JS.Class.Instance { + // export class Object { + // + // // TODO: Could copy? + // get initial(): Ray.Any { return this._initial(); } set initial(initial: Ray.Any) { this._initial = initial; } protected _initial: Ray.Any; + // get self(): Ray.Any { return this._self(); } set self(self: Ray.Any) { this._self = self; } protected _self: Ray.Any; + // get terminal(): Ray.Any { return this._terminal(); } set terminal(terminal: Ray.Any) { this._terminal = terminal; } protected _terminal: Ray.Any; + // + // protected constructor({ initial, self, terminal }: { initial?: Ray.Any, self?: Ray.Any, terminal?: Ray.Any } = {}) { + // + // this._initial = initial ?? Ray.none.memoized; + // this._self = self ?? Ray.self_reference; + // this._terminal = terminal ?? Ray.none.memoized; + // } + // } + + /** A simplistic compiler for Ray */ + export namespace Compiler { // TODO Ray is Compiler - static New = (constructor?: Ray.Constructor): Ray.Instance => new Ray.Instance(constructor); + /** + * TODO: Compiler could have things like other composed rays which tell it cares about the other (even if that's correct or not??) + * + * + * TODO: Do I want to keep the is_equiv/is_composed pattern? Or simplify to one of the two? + * + * // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY + * + * TODO + * - Compose empty as first element? Disregard none to first elemn? Or not?? + * + * TODO; Impl + * - Generally, return something which knows where all continuations are. + * - Generator/step function/... ; with no assumption of halting, but allow to hook into any step. + * - Cache: + * - Control of (non-/)lazyness of functions + * - None as, first time called, memoize func. + * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence + * - a.orbit() -> a.orbit(a) + * // TODO: Should be automatic? is_orbit() or any method without arguments is a.is_orbit(a.self()) ?? not a.is_orbit(a) ; ??? + * + * - .initial/.terminal can be seen as a particular connection on .self, which .self ignores? + * + * TODO: Allow hooking + * + * TODO: Testing + * - Test if references hold after equivalence/composition... + * + * TODO: After initial demo: + * - Allow mapping/finding of other implementations regarding some equiv funcs (like different ways of implementing using NAND etc...) + * + * Arbitrary. + */ + } + export type Constructor = { proxy?: ProxyHandler, debug?: Debug.Listener, } - listeners: Debug.Listener[]; + export class Instance extends JS.Class.Instance { - // get initial(): Ray.Any { return this._initial.call(this.proxy); } set initial(initial: Ray.FunctionConstructor) { this._initial = Ray.Function.New(initial); } protected _initial: Ray.Function; - // get self(): Ray.Any { return this._self.call(this.proxy); } set self(self: Ray.FunctionConstructor) { this._self = Ray.Function.New(self); } protected _self: Ray.Function; - // get terminal(): Ray.Any { return this._terminal.call(this.proxy); } set terminal(terminal: Ray.FunctionConstructor) { this._terminal = Ray.Function.New(terminal); } protected _terminal: Ray.Function; + listeners: Debug.Listener[]; - protected constructor({ - // initial, self, terminal + constructor({ proxy, debug, }: Ray.Constructor = {}) { super({ proxy: proxy ?? Ray.ProxyHandlers.Default }); this.listeners = debug ? [debug] : []; - - // this._initial = Ray.Function.New(initial ?? Ray.None); - // this._self = Ray.Function.New(self ?? this.proxy); - // this._terminal = Ray.Function.New(terminal ?? Ray.None); } /** Used to jump out of the proxy. */ @@ -96,41 +128,6 @@ namespace Ray { } - export class Compiler { // Ray is Compiler - - /** - * TODO: Compiler could have things like other composed rays which tell it cares about the other (even if that's correct or not??) - * - * - * TODO: Do I want to keep the is_equiv/is_composed pattern? Or simplify to one of the two? - * - * // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY - * - * TODO - * - Compose empty as first element? Disregard none to first elemn? Or not?? - * - * TODO; Impl - * - Generally, return something which knows where all continuations are. - * - Generator/step function/... ; with no assumption of halting, but allow to hook into any step. - * - Cache: - * - Control of (non-/)lazyness of functions - * - None as, first time called, memoize func. - * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence - * - a.orbit() -> a.orbit(a) - * // TODO: Should be automatic? is_orbit() or any method without arguments is a.is_orbit(a.self()) ?? not a.is_orbit(a) ; ??? - * - * - .initial/.terminal can be seen as a particular connection on .self, which .self ignores? - * - * TODO: Allow hooking - * - * TODO: Testing - * - Test if references hold after equivalence/composition... - * - * TODO: After initial demo: - * - Allow mapping/finding of other implementations regarding some equiv funcs (like different ways of implementing using NAND etc...) - */ - - } export namespace ProxyHandlers { @@ -372,17 +369,13 @@ namespace Ray { self => self.is_none().not() ); - export const self_reference = Ray.Function.Self.Impl( - self => self - ); - /** * @see "Continuations as Equivalence (can often be done in parallel - not generally)": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence */ // @alias('merge, 'continues_with', 'compose') export const compose = Ray.Function.Self.Binary( - (a, b) => a.terminal().equivalent(b.initial()) - ); + (a, b) => a.terminal().equivalent(b.initial()) + ); /** * "Composing an terminal & initial boundary" @@ -399,7 +392,12 @@ namespace Ray { * - TODO: If we're only doing one end: This already assumes they are connected on the other end. * - TODO: should be a connection here, with is_composed ; or "reference.is_equivalent" so that you can drop one of the sides, or both. */ - (a, b) => ( b.last().compose(a.first()) ).and( a.first().compose(b.last()) ) + (a, b) => { + b.last().compose(a.first()); + a.first().compose(b.last()); + + return a; // ? + } ); /** @@ -442,8 +440,6 @@ namespace Ray { (a) => { throw new NotImplementedError(); } ); - - // TODO: .next but arbitrary step?? export const next = Ray.Function.Self.Impl((self) => { throw new NotImplementedError(); return self; @@ -510,8 +506,6 @@ namespace Ray { // TODO Relies heavily on the execution layer to copy initial/terminal etc... ; and an is_orbit check before calling copy again. - Then again on the execution layer it can lazily do this copy (by not evaluating (i.e.) traversing everywhere), or it first does this traversing directly. ); - export const none = Ray.Op.Zeroary.All.none; // TODO FOR ALL OPS, ? automatic, or just put them here. - /** * Placing existing structure on a new Reference, Boundary or Vertex: */ @@ -550,6 +544,9 @@ namespace Ray { return initial; }); + export const memoized = Ray.Function.Self.Impl( + self => { throw new NotImplementedError(); } + ); } } @@ -564,6 +561,11 @@ namespace Ray { export const number = (number: number) => { throw new NotImplementedError(); } + export const self_reference = Ray.Function.Self.Impl( + self => self + ); + export const none = Ray.Op.Zeroary.All.none; // TODO FOR ALL OPS, ? automatic, or just put them here. + // export const Boundary = { INITIAL: Type.INITIAL, TERMINAL: Type.TERMINAL }; TODO: LIST O // TODO CAN ALSO BE ZERO-ARY.. @@ -572,8 +574,17 @@ namespace Ray { (a, size) => { throw new NotImplementedError(); } ); // @alias('bit') - // export const boolean = size(2); + export const boolean = size(2); + export const vertex = Ray.Function.Self.Impl( + (self) => { throw new NotImplementedError(); } + ); + export const initial = Ray.Function.Self.Impl( + (self) => { throw new NotImplementedError(); } + ); + export const terminal = Ray.Function.Self.Impl( + (self) => { throw new NotImplementedError(); } + ); } export default Ray; \ No newline at end of file diff --git a/orbitmines.com/src/@orbitmines/explorer/Ray2.ts b/orbitmines.com/src/@orbitmines/explorer/Ray2.ts index 7739a75..3a1d57d 100644 --- a/orbitmines.com/src/@orbitmines/explorer/Ray2.ts +++ b/orbitmines.com/src/@orbitmines/explorer/Ray2.ts @@ -60,8 +60,6 @@ export class Ray { initial_vertex.compose(terminal_vertex); - // TODO BETTER DEBUG - return Ray.directions.next(terminal_vertex); } private ___as_vertices = (): [Ray, Ray] => { @@ -222,15 +220,6 @@ export class Ray { return copy; } - *traverse(step: Ray.FunctionImpl = Ray.directions.next): Generator { - // TODO: Also to ___func?? - - if (this.type !== RayType.VERTEX) - throw new NotImplementedError(`[${this.type}]`); - - yield *this.___next({step}); - } - *___next({ step = Ray.directions.next, } = {}): Generator { @@ -437,12 +426,6 @@ export class Ray { // throw new PreventsImplementationBug(`${pointers.length} left`) } - - /** - * - * TODO: - * - This needs something much smarter at some point... - */ all = (step: Ray.FunctionImpl = Ray.directions.next): { [key: string | symbol]: Ray.Any } & any => { return new Proxy(this, { From acf70fbfeb862171df6e695c8f3eae5af5687a0a Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 29 Jan 2024 17:44:57 +0100 Subject: [PATCH 131/138] 2024/01/29 - Some thinking on runtime/compiler differences --- environments/javascript/@orbitmines/rays/src/Ray.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index 6edc32d..cf44f0a 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -440,6 +440,7 @@ namespace Ray { (a) => { throw new NotImplementedError(); } ); + // TODO: .terminal/.initial is self() vs self.not() export const next = Ray.Function.Self.Impl((self) => { throw new NotImplementedError(); return self; From 451cdc97575926979ba0ea7c8f9cede2c9b20de4 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 29 Jan 2024 18:07:46 +0100 Subject: [PATCH 132/138] 2024/01/29 - Move some stuff around --- .../src/@orbitmines/explorer => _temp}/JS2.ts | 0 .../explorer => _temp}/OrbitMinesExplorer.tsx | 0 .../REFACTOR_AFTER_WORKING_TRAVERSE.md | 0 .../explorer => _temp}/REFACTOR_RENDER.md | 0 .../@orbitmines/explorer => _temp}/Ray2.ts | 0 .../explorer => _temp}/Visualization.tsx | 0 .../explorer => _temp}/debug/DebugCanvas.tsx | 0 .../debug/QuickVisualizationInterface.tsx | 0 .../javascript/@orbitmines/rays/src/Ray.ts | 5 + .../javascript/@orbitmines/rays/tsconfig.json | 2 +- .../src/@orbitmines/Visualization.tsx | 306 +++ .../@orbitmines/external/chyp/Chyp.spec.ts | 28 - .../src/@orbitmines/external/chyp/Chyp.ts | 155 -- .../@orbitmines/external/chyp/ChypCanvas.tsx | 684 ------- .../external/chyp/Chyp_naive_pass.ts | 1665 ----------------- .../src/@orbitmines/external/chyp/README.md | 9 - .../src/@orbitmines/external/chyp/examples.ts | 76 - orbitmines.com/src/App.tsx | 23 +- orbitmines.com/src/lib/paper/Paper.tsx | 2 +- .../src/routes/papers/2023.FadiShawki.tsx | 3 +- .../src/routes/papers/2023.OnOrbits.tsx | 11 +- 21 files changed, 326 insertions(+), 2643 deletions(-) rename {orbitmines.com/src/@orbitmines/explorer => _temp}/JS2.ts (100%) rename {orbitmines.com/src/@orbitmines/explorer => _temp}/OrbitMinesExplorer.tsx (100%) rename {orbitmines.com/src/@orbitmines/explorer => _temp}/REFACTOR_AFTER_WORKING_TRAVERSE.md (100%) rename {orbitmines.com/src/@orbitmines/explorer => _temp}/REFACTOR_RENDER.md (100%) rename {orbitmines.com/src/@orbitmines/explorer => _temp}/Ray2.ts (100%) rename {orbitmines.com/src/@orbitmines/explorer => _temp}/Visualization.tsx (100%) rename {orbitmines.com/src/@orbitmines/explorer => _temp}/debug/DebugCanvas.tsx (100%) rename {orbitmines.com/src/@orbitmines/explorer => _temp}/debug/QuickVisualizationInterface.tsx (100%) create mode 100644 orbitmines.com/src/@orbitmines/Visualization.tsx delete mode 100644 orbitmines.com/src/@orbitmines/external/chyp/Chyp.spec.ts delete mode 100644 orbitmines.com/src/@orbitmines/external/chyp/Chyp.ts delete mode 100644 orbitmines.com/src/@orbitmines/external/chyp/ChypCanvas.tsx delete mode 100644 orbitmines.com/src/@orbitmines/external/chyp/Chyp_naive_pass.ts delete mode 100644 orbitmines.com/src/@orbitmines/external/chyp/README.md delete mode 100644 orbitmines.com/src/@orbitmines/external/chyp/examples.ts diff --git a/orbitmines.com/src/@orbitmines/explorer/JS2.ts b/_temp/JS2.ts similarity index 100% rename from orbitmines.com/src/@orbitmines/explorer/JS2.ts rename to _temp/JS2.ts diff --git a/orbitmines.com/src/@orbitmines/explorer/OrbitMinesExplorer.tsx b/_temp/OrbitMinesExplorer.tsx similarity index 100% rename from orbitmines.com/src/@orbitmines/explorer/OrbitMinesExplorer.tsx rename to _temp/OrbitMinesExplorer.tsx diff --git a/orbitmines.com/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md b/_temp/REFACTOR_AFTER_WORKING_TRAVERSE.md similarity index 100% rename from orbitmines.com/src/@orbitmines/explorer/REFACTOR_AFTER_WORKING_TRAVERSE.md rename to _temp/REFACTOR_AFTER_WORKING_TRAVERSE.md diff --git a/orbitmines.com/src/@orbitmines/explorer/REFACTOR_RENDER.md b/_temp/REFACTOR_RENDER.md similarity index 100% rename from orbitmines.com/src/@orbitmines/explorer/REFACTOR_RENDER.md rename to _temp/REFACTOR_RENDER.md diff --git a/orbitmines.com/src/@orbitmines/explorer/Ray2.ts b/_temp/Ray2.ts similarity index 100% rename from orbitmines.com/src/@orbitmines/explorer/Ray2.ts rename to _temp/Ray2.ts diff --git a/orbitmines.com/src/@orbitmines/explorer/Visualization.tsx b/_temp/Visualization.tsx similarity index 100% rename from orbitmines.com/src/@orbitmines/explorer/Visualization.tsx rename to _temp/Visualization.tsx diff --git a/orbitmines.com/src/@orbitmines/explorer/debug/DebugCanvas.tsx b/_temp/debug/DebugCanvas.tsx similarity index 100% rename from orbitmines.com/src/@orbitmines/explorer/debug/DebugCanvas.tsx rename to _temp/debug/DebugCanvas.tsx diff --git a/orbitmines.com/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx b/_temp/debug/QuickVisualizationInterface.tsx similarity index 100% rename from orbitmines.com/src/@orbitmines/explorer/debug/QuickVisualizationInterface.tsx rename to _temp/debug/QuickVisualizationInterface.tsx diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index cf44f0a..58b1377 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -520,6 +520,8 @@ namespace Ray { self => none().self = self ); + // TODO as_reference.as_vertex instead of as_vertex ignorant by default? + export const as_vertex = Ray.Function.Self.Impl((self) => { const vertex = Ray.Op.Zeroary.All.none(); vertex.initial = self_reference; @@ -545,6 +547,9 @@ namespace Ray { return initial; }); + /** + * Any arbitrary direction, where .not (or reversing the direction) relies on some memory mechanism + */ export const memoized = Ray.Function.Self.Impl( self => { throw new NotImplementedError(); } ); diff --git a/environments/javascript/@orbitmines/rays/tsconfig.json b/environments/javascript/@orbitmines/rays/tsconfig.json index 1941385..05ddc21 100755 --- a/environments/javascript/@orbitmines/rays/tsconfig.json +++ b/environments/javascript/@orbitmines/rays/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2015", + "target": "esnext", "lib": ["esnext"], "allowJs": true, "skipLibCheck": true, diff --git a/orbitmines.com/src/@orbitmines/Visualization.tsx b/orbitmines.com/src/@orbitmines/Visualization.tsx new file mode 100644 index 0000000..215553e --- /dev/null +++ b/orbitmines.com/src/@orbitmines/Visualization.tsx @@ -0,0 +1,306 @@ +import React, {useCallback, useEffect, useRef, useState} from 'react'; +import {Canvas} from "@react-three/fiber"; +import {ACESFilmicToneMapping, SRGBColorSpace} from "three"; +import WEBGL from "three/examples/jsm/capabilities/WebGL"; +import {useSearchParams} from "react-router-dom"; +import {toPng} from "html-to-image"; +import {Button} from "@blueprintjs/core"; +import isWebGLAvailable = WEBGL.isWebGLAvailable; +import {PaperProps} from "../lib/paper/Paper"; +import {Children} from "../lib/typescript/React"; +import {Col, Row} from "../lib/layout/flexbox"; +import Ray from "@orbitmines/rays"; + +export const NoWebGL = () => { + return
No WebGL
+} + +export type VisualizationProps = { + context: Omit, + alt: string, +} + +const Visualization = ({ray}: { ray: Ray.Any }) => { + return + + +} + +export const CachedVisualizationCanvas = ( + { + alt, + context, + children, + ...props + }: React.HTMLAttributes & Children & VisualizationProps +) => { + const ref = useRef(null); + const [useImage, setUseImage] = useState(true); + let generate; + try { + const [params] = useSearchParams(); + + generate = params.get('generate'); + } catch (e) { + generate = 'pdf'; + } + + const exportPng = useCallback(() => { + if (ref === null) + return; + + toPng(ref.current, { + cacheBust: true, + // backgroundColor: '#1C2127' + }) + .then((dataUrl) => { + const link = document.createElement('a') + link.download = `${alt}.png` + link.href = dataUrl + link.click() + }) + .catch((err) => { + console.log(err) + }); + }, [ref]); + + if (context.link === undefined) + throw 'Cannot have the paper\'s link be undefined when using a cached canvas.' + + const canvasUrl = `${context.link.replace("https://orbitmines.com", "")}/images/${alt}.png`; + + useEffect(() => { + // Just a quick hack to check if it's loaded (could draw it on the canvas from here, ?) + + const img = new Image(); + img.src = canvasUrl; + img.onerror = () => { + setUseImage(false); + }; + }, []); + + if (useImage) { + return + + + } + + return
+
+ + {children} + +
+ {generate === 'canvas' ? + {/* eslint-disable-next-line react/jsx-no-undef */} +
+} + +export const CanvasContainer = ({ + children, + ...props + }: React.HTMLAttributes & Children) => (
+ {children} +
) + +export const ThreeJS = ({ref, children}: Children & { ref?: React.MutableRefObject}) => { + // https://threejs.org/docs/#manual/en/introduction/WebGL-compatibility-check + if (!isWebGLAvailable()) + return ; + + // console.log('webgl2', isWebGLAvailable()); + + /* + https://docs.pmnd.rs/react-three-fiber/api/canvas + - Sets up a Scene and a Camera, the basic building blocks necessary for rendering + - Renders our scene every frame, you do not need a traditional render-loop + + - Canvas is responsive to fit the parent node, so you can control how big it is by changing the parents width and height, in this case #canvas-container. + */ + return + {children} + + {/*/!* https://threejs.org/docs/#api/en/objects/Mesh *!/*/} + {/**/} + {/* /!**/} + {/* https://threejs.org/docs/#api/en/lights/AmbientLight*/} + {/* - This light globally illuminates all objects in the scene equally.*/} + {/* - This light cannot be used to cast shadows as it does not have a direction.*/} + {/* *!/*/} + + {/* /!* https://threejs.org/docs/#api/en/lights/DirectionalLight *!/*/} + {/* /!**!/*/} + + {/* /!* https://threejs.org/docs/#api/en/geometries/BoxGeometry *!/*/} + {/* */} + + {/* /!* https://threejs.org/docs/#api/en/materials/MeshStandardMaterial *!/*/} + {/* */} + {/**/} + + {/**/} + + {/* https://docs.pmnd.rs/react-postprocessing/selection */} + {/**/} + {/* /!* https://docs.pmnd.rs/react-postprocessing/effect-composer *!/*/} + {/* */} + {/* */} + {/* */} + {/**/} + + {/**/} + + {/**/} + + {/**/} + + {/**/} + + {/**/} + {/* /!* https://threejs.org/docs/#api/en/materials/MeshStandardMaterial *!/*/} + {/* */} + {/**/} + {/**/} + {/* /!* https://threejs.org/docs/#api/en/materials/MeshStandardMaterial *!/*/} + {/* */} + {/**/} + {/**/} + {/* /!* https://threejs.org/docs/#api/en/materials/MeshStandardMaterial *!/*/} + {/* */} + {/**/} + + {/**/} + {/* /!* https://threejs.org/docs/#api/en/materials/MeshStandardMaterial *!/*/} + {/* */} + {/**/} + + {/**/} + + +} + +export const VisualizationCanvas = ( + { + children, + ...props + }: React.HTMLAttributes & Children +) => { + + return ( + // ThreeJS: https://threejs.org/ + // React Three Fiber: https://docs.pmnd.rs/react-three-fiber/api/objects + // https://github.com/pmndrs/drei#readme + + {children} + + ); +}; + +export default Visualization; \ No newline at end of file diff --git a/orbitmines.com/src/@orbitmines/external/chyp/Chyp.spec.ts b/orbitmines.com/src/@orbitmines/external/chyp/Chyp.spec.ts deleted file mode 100644 index c98e088..0000000 --- a/orbitmines.com/src/@orbitmines/external/chyp/Chyp.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ - -describe("Chyp", () => { - describe(".Graph", () => { - test(".set_inputs", () => { - // const graph = Chyp.Graph.new() - // .set_inputs(Ray.vertex().o({ js: 'B' }).as_arbitrary()) - // .set_inputs(Ray.vertex().o({ js: 'A' }).as_arbitrary()); - // - // expect(graph.inputs.as_reference().any.js).toBe('A'); - // expect(graph.initial.as_reference().any.js).toBe('A'); - // expect(graph.inputs.as_reference().any.js).toBe(graph.initial.as_reference().any.js); - // expect(graph.inputs).toBe(graph.initial); - }); - // - }); - // describe(".Rule", () => { - // test(".name", () => { - // let rule = Chyp.Rule.new(); - // rule.name = 'test'; - // - // expect(rule.name).toBe('test'); - // expect(rule.reverse.any.name).toBe('-test'); - // // expect(rule.reverse.reverse.any.name).toBe('test'); - // - // }); - // }); -}); - diff --git a/orbitmines.com/src/@orbitmines/external/chyp/Chyp.ts b/orbitmines.com/src/@orbitmines/external/chyp/Chyp.ts deleted file mode 100644 index 8c5f5d6..0000000 --- a/orbitmines.com/src/@orbitmines/external/chyp/Chyp.ts +++ /dev/null @@ -1,155 +0,0 @@ -import {Ray} from "../../explorer/Ray"; -import {NotImplementedError} from "../../explorer/errors/errors"; -import JS from "../../explorer/JS"; - -/** - * An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Ray. - * - * **What is this?, What are Rays?** - * - * See the `README.md` at [github.com/orbitmines/orbitmines.com](https://github.com/orbitmines/orbitmines.com). Or locally: [README.md](../../../../README.md) - * - * **Why is this interface here?** - * - * Note that this is mainly here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. Or considered as a legacy translation, which will be accessibly through OrbitMines. - */ - -/** TODO errors probably hooked as a boolean, one successful the other not */ -export class GraphError extends Error {} -export class RuleError extends Error {} -export class RuntimeError extends Error {} -export class StopIteration extends Error {} - -export namespace Chyp { - - export type VData = Vertex; export class Vertex extends Ray { - - static new = (): Vertex => { - return new Vertex(); - } - - protected constructor() { - super(); - } - - // Vertex.in_edges = Ray.initial - get in_edges(): Ray.Any { return this.initial; } set in_edges(ray: JS.ParameterlessFunction) { this.initial = ray; } - - // Vertex.out_edges = Ray.terminal - get out_edges(): Ray.Any { return this.terminal; } set out_edges(ray: JS.ParameterlessFunction) { this.terminal = ray; } - - } - - export type EData = Edge; export class Edge extends Ray { - - // Edge.source = Ray.initial - get source(): Ray.Any { return this.initial; } set source(ray: JS.ParameterlessFunction) { this.initial = ray; } - get s(): Ray.Any { return this.initial; } set s(ray: JS.ParameterlessFunction) { this.initial = ray; } - - // Edge.targets = Ray.terminal - get target(): Ray.Any { return this.terminal; } set target(ray: JS.ParameterlessFunction) { this.terminal = ray; } - get t(): Ray.Any { return this.terminal; } set t(ray: JS.ParameterlessFunction) { this.terminal = ray; } - - } - - export class Match extends Ray { - - /** - * | <-- (vertex/edge)_map to (vertex/edge)_image - * _____|_____ - * / | \ - * Domain: [--|--][--|--][--|--] <-- Any of the matching structure on 'domain' is '_map'. - * | | | (is_total = true, if everything is on '_map') - * | | | - * Codomain: [--|--][--|--][--|--] <-- Any of the matching structure on 'codomain' is '_image'. - * | | | (is_surjective = true, if everything is on '_image') - */ - - static new = (): Match => { - return new Match(); - } - - protected constructor() { - super(); - } - - // Match.domain = Ray.initial - get domain(): Ray.Any { return this.initial; } set domain(ray: JS.ParameterlessFunction) { this.initial = ray; } - - // Match.codomain = Ray.terminal - get codomain(): Ray.Any { return this.terminal; } set codomain(ray: JS.ParameterlessFunction) { this.terminal = ray; } - - } - - export class Rule extends Ray { - - static new = (): Rule => { - return new Rule(); - } - - protected constructor() { - super(); - } - - // Rule.lhs = Ray.initial - get lhs(): Ray.Any { return this.initial; } set lhs(ray: JS.ParameterlessFunction) { this.initial = ray; } - - // Rule.rhs = Ray.terminal - get rhs(): Ray.Any { return this.terminal; } set rhs(ray: JS.ParameterlessFunction) { this.terminal = ray; } - - /** - * TODO: We can use the same implementation to rewrite where there's not necessarily a match between initial/terminal side of a rule. - * - * TODO: In general, we can just assume each lhs, has some link to some rhs, and not go through 'The Rule', and simply if lhs terminates, it terminates, if additional ones are initialized through rhs, so be it. - Set this up after this implementation where we reference an entire thing from a single perspective. - */ - validate = () => { - // TODO: Call from somewhere. - - if (!this.initial.is_equivalent(this.terminal)) - throw new RuleError('LHS (Initial) !== RHS (Terminal)'); - - // TODO: Or each check separately - // if (!this.initial.initial.is_equivalent(this.terminal.initial)) - // throw new RuleError('Initial.Initial (LHS.Domain) !== Terminal.Initial (RHS.Domain)'); - // if (!this.initial.terminal.is_equivalent(this.terminal.terminal)) - // throw new RuleError('Initial.Terminal (LHS.Codomain) !== Terminal.Terminal (RHS.Codomain)'); - } - - name = this.property('name', ''); - - override get reverse(): Ray.Any { - // TODO remove this hacky thing - just tries to us -a / a - - const name = this.name.startsWith('-') ? this.name.substring(1) : `-${this.name}`; - - return super.reverse.o({ name }); - } - - dpo = (match: Match): Ray.Any => { - throw new NotImplementedError(); - } - - } - - export class Graph extends Ray { - - static new = (): Graph => { - return new Graph(); - } - - protected constructor() { - super(); - } - - // Graph.inputs = Ray.initial - get inputs(): Ray.Any { return this.initial; } set inputs(ray: JS.ParameterlessFunction) { this.initial = ray; } - set_inputs = (ray: JS.ParameterlessFunction): Graph => { this.inputs = ray; return this; } - add_inputs = (ray: Ray.Any): Graph => { this.inputs.compose(ray); return this; } - // Graph.inputs = Ray.terminal - get outputs(): Ray.Any { return this.terminal; } set outputs(ray: JS.ParameterlessFunction) { this.terminal = ray; } - set_outputs = (ray: JS.ParameterlessFunction): Graph => { this.outputs = ray; return this; } - add_outputs = (ray: Ray.Any): Graph => { this.outputs.compose(ray); return this; } - - } - -} \ No newline at end of file diff --git a/orbitmines.com/src/@orbitmines/external/chyp/ChypCanvas.tsx b/orbitmines.com/src/@orbitmines/external/chyp/ChypCanvas.tsx deleted file mode 100644 index 0d032f6..0000000 --- a/orbitmines.com/src/@orbitmines/external/chyp/ChypCanvas.tsx +++ /dev/null @@ -1,684 +0,0 @@ -import React, {useEffect, useRef, useState} from "react"; -import IEventListener from "../../js/react/IEventListener"; -import {VisualizationCanvas} from "../../explorer/Visualization"; -import { - _Continuation, - _Vertex, - add, - add_, - AutoVertex, - circle, - InterfaceOptions, - Line, - torus -} from "../../explorer/OrbitMinesExplorer"; -import {useHotkeys} from "../../js/react/hooks/useHotkeys"; -import {DebugResult, Ray, RayType} from "../../explorer/Ray"; -import {HotkeyConfig} from "@blueprintjs/core/src/hooks/hotkeys/hotkeyConfig"; -import _ from "lodash"; -import {useThree} from "@react-three/fiber"; -import {Render, StatsPanels} from "../../explorer/debug/DebugCanvas"; - -// TODO: Put the graphs setc at the top, invis lines, then draw them on hover, and maybe make surrounding stuff less visiable. -// TODO: make some function which uses a custom input like position of the interface as the thing which breaks equivalences - ignorances. Basically a custom "equivalency function" -// TODO; Key to output javascript compilation targets in console, array, .. etc. -// const Debug = () => { -// const groups: string[][] = []; -// _.values(debug).forEach(ray => { -// for (let group of groups) { -// if (group.includes(ray.label) || group.includes(ray.vertex)) { -// group.push(...[ray.label, ray.vertex].filter(l => l !== 'None')); -// return; -// } -// } -// -// groups.push([ray.label, ray.vertex].filter(l => l !== 'None')); -// }); -// -// const group = (l: string): string[] => groups.find(group => group.includes(l))!; -// const group_index = (l: string): number => groups.indexOf(group(l)); -// const index_in_group = (l: string): number => group(l).indexOf(l); -// -// -// //TODO: do the same for group in initial/yerminal -// return <> -// {/*
*/} -// {_.values(debug).map(((_ray, index) => { -// let ray = { -// ...debug[_ray.label] -// } -// -// const color = { -// [RayType.VERTEX]: 'orange', -// [RayType.TERMINAL]: '#FF5555', -// [RayType.INITIAL]: '#5555FF', -// [RayType.REFERENCE]: '#555555', -// }[ray.type]; -// -// const group_x = _.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position)).map(position => position[0])[0]; -// // console.log(_.compact(group(ray.label).map(l => (debug[l] as InterfaceOptions).position))) -// -// ray = { -// ...ray, -// ...({ -// color, -// scale: 1.5, -// // rotation: Ray.Any.type == RayType.REFERENCE ? [0, 0, Math.PI / 6] : [0, 0, 0], -// position: [ -// group_x ?? group_index(ray.label) * 20 * 1.5, -// // (index_in_group(ray.label) + group_index(ray.label) + (group_x ? 0: 1)) * 30 * 1.5, -// index * 20 * 1.5, -// 0 -// ] -// } as InterfaceOptions) -// } -// -// debug[_ray.label] = ray; -// -// const _default: Required = { -// position: [0, 0, 0], -// rotation: [0, 0, 0], -// scale: 1, -// color: 'orange', -// ..._.pick(ray, 'position', 'rotation', 'scale', 'color'), -// } -// -// // console.log(ray.label, [ray.initial, ray.vertex, ray.terminal].toString()) -// -// const initial: Required = { ..._default, position: [-20 * _default.scale, 0, 0] }; -// -// // Vertex as the origin for rotation -// const vertex: Required = { ..._default, position: [0, 0, 0] } //, ...ray.vertex }; -// const terminal: Required = { ..._default, position: [20 * _default.scale, 0, 0] }; -// -// const Group = ({ children }: Children) => { -// return -// {children} -// -// } -// -// const None = (options: InterfaceOptions) => (<_Continuation {...options} color="#AA0000" scale={1} />) -// -// const Extreme = ({type}: { type: Ray.AnyType.INITIAL | RayType.TERMINAL }) => { -// const options = type === RayType.INITIAL ? initial : terminal; -// -// switch (ray.type) { -// case RayType.REFERENCE: -// case RayType.VERTEX: { -// const a = type === RayType.INITIAL ? { terminal: vertex } : { initial: vertex }; -// return ; -// } -// case type: { -// return ; -// } -// case (type === RayType.INITIAL ? RayType.TERMINAL : Ray.AnyType.INITIAL): { -// return <> -// } -// } -// } -// -// return -// -// -// -// -// }))} -// -// {groups.map(group => <> -// {group.map(l => )} -// )} -// {/*
*/} -// -// } - -const ___index = (ray: Ray.Any): number => { - switch (ray.type) { - case RayType.REFERENCE: - return ray.___any.index ?? 0; - case RayType.INITIAL: - return ray.follow().___any.index ?? 0; - case RayType.TERMINAL: - return ray.follow(Ray.directions.previous).___any.index ?? 0; - case RayType.VERTEX: - return ray.___any.index ?? 0; - } -} - -export const Render2 = ({ ray, Interface, show = { initial: true, terminal: true } }: { ray: Ray.Any, Interface: Ray.Any, index: number, show?: { initial: boolean, terminal: boolean } }) => { - const index = ___index(ray); - let added = [15 * index, 60 * index, 0]; - - const initial: Required = ray.follow(Ray.directions.previous).render_options(Interface); - initial.position = add_(initial.position, added); - const vertex: Required = ray.render_options(Interface); - vertex.position = add_(vertex.position, added); - const terminal: Required = ray.follow().render_options(Interface); - terminal.position = add_(terminal.position, added); - - switch (ray.type) { - case RayType.REFERENCE: - return <_Vertex position={vertex.position} rotation={[0, 0, Math.PI / 2]} scale={vertex.scale / 2} color="#555555" /> - case RayType.INITIAL: { - const diff = [-15, -15, 0]; - - return - {!show.initial ? : - - - - - - } - - - - - - - - <_Continuation {...vertex} position={add_(vertex.position, !show.initial && ray.type === RayType.INITIAL ? [-15, -15, 0] : [0, 0, 0])} /> - - - {!show.initial ? : - - <_Continuation {...vertex} position={add_(vertex.position, diff)} color="#FF5555"/> - <_Continuation {...vertex} position={add_(vertex.position, diff, [-30, 0, 0])} scale={vertex.scale / 3 * 2} - color="#AA0000"/> - } - - } - case RayType.TERMINAL: { - const diff = [15, 15, 0]; - - return - {!show.terminal ? : - - - - - - - - } - - - - - - <_Continuation {...vertex} position={add_(vertex.position, !show.terminal && ray.type === RayType.TERMINAL ? [15, 15, 0] : [0, 0, 0])} /> - - - {!show.terminal ? : - - <_Continuation {...vertex} position={add_(vertex.position, diff)} color="#5555FF" /> - <_Continuation {...vertex} position={add_(vertex.position, diff, [30, 0, 0])} scale={vertex.scale / 3 * 2} color="#AA0000"/> - } - - } - case RayType.VERTEX: { - return <_Vertex {...vertex} /> - } - } -} - -export const DebugInterface2 = ({scale = 1.5}: InterfaceOptions) => { - const ref = useRef(); - const hotkeyConfig = useHotkeys(); - - const { - gl: renderer, - camera, - scene, - raycaster - } = useThree(); - - const space_between = 20 * scale; - - const [Interface] = useState(Ray.vertex().o({ - selection: Ray.Any.vertex().o2({ - initial: { position: [-space_between, 0, 0], scale, color: 'orange' }, - vertex: { index: 0, position: [0, 0, 0], scale, color: 'orange' }, - terminal: { position: [space_between, 0, 0 ], scale, color: 'orange' }, - }).as_reference().o({ - position: [0, 0, 0], - scale, - rotation: [0, 0, Math.PI / 6 ], - color: '#555555' - }), - rays: [] as Ray[], - stats: false, - controls: { - hotkeys: [ - { - combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { - const { selection, rays } = Interface.___any; - - const current = Interface.___any.selection.render_options(Interface); - - const next = Ray.vertex().o2({ - initial: { position: add_(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, - vertex: { index: Interface.___any.selection.___any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, - terminal: { position: add_(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } - }).as_reference().o({ - ...selection.as_reference().render_options(Interface), - position: add(selection.___any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) - }); - - Interface.___any.selection = selection.compose(next); - Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray.Any) => { - ray.___any.traversed = true; - return ray.as_reference(); - }); - - } - }, - { - combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { - if (Interface.___any.Ray.length === 0) - return; - - Interface.___any.selection = Interface.___any.selection.pop(); - Interface.___any.selection.o({ - position: Interface.___any.selection.render_options(Interface).position - }); // TODO, Same with this. - Interface.___any.selection.self.terminal.o({ - position: add(Interface.___any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' - }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. - - Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray.Any) => { - ray.___any.traversed = true; - return ray.as_reference(); - }); - - if (Interface.___any.length === 0) { - Interface.___any.selection.___any.position = [0, 0, 0] - return; - } - } - }, - { - combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { - const { selection, rays } = Interface.___any; - - Interface.___any.rays = Ray.flatMap((ray: Ray.Any) => [ - ray, - // Ray.js("A").as_reference().o({ - // // ...ray.o, - // position: add(ray.___any.position ?? [0, 0, 0], [0, i * 2, 0]) - // }), - // Ray.js("A").as_reference().o({ - // // ...ray.o, - // position: Ray.Any.___any.position, - // rotation: [0, 0, Math.PI / 2] - // }), - // Ray.js("A").as_reference().o({ - // // ...ray.o, - // position: add(ray.___any.position ?? [0, 0, 0], [0, i * 2, 0]), - // rotation: [0, 0, Math.PI / 2] - // }) - ]); - - // Chyp_naieve_pass.___any.selection = Chyp_naieve_pass; - - // selection.o({...selection.o, position: add(selection.___any.position ?? [0, 0, 0], [0, i * 2, 0])}) - - // selection.compose( - - // ); - } - }, - { - combo: "/", global: true, label: "", onKeyDown: () => { - console.log('---------') - console.log(`Debugging: ${Interface.___any.selection.self.label} (type=${Interface.___any.selection.type})`) - console.log(`Ray.length at pos=[${Interface.___any.selection.render_options(Interface).position}]: ${Interface.___any.Ray.filter((ray: Ray.Any) => - _.isEqual( - Interface.___any.selection.render_options.position, - ray.render_options(Interface).position - ) - ).length} / ${Interface.___any.Ray.length}`) - console.log('ref', Interface.___any.selection) - console.log('ref.self', Interface.___any.selection.self) - - const debug: DebugResult = {}; - Interface.___any.selection.self.debug(debug); - console.log('ref.debug', debug); - Interface.___any.Ray.forEach((ray: Ray.Any) => Ray.Any.debug(debug)); - console.log('Ray.debug', debug); - - } - }, - { - combo: "f3", global: true, label: "Show stats Panel", onKeyDown: (e) => { - e.preventDefault(); - Interface.___any.stats = !Interface.___any.stats; - } - }, - ] as HotkeyConfig[] - } - })); - - // useEffect(() => { - // TODO: Eventually goes over maximum size of react-debug callstack when updates each frame like this. - hotkeyConfig.set(...Interface.___any.controls.hotkeys); - // }, [Interface.___any.controls.___any.hotkeys]); - - const index = ___index(Interface.___any.selection); - const added = [15 * index, 60 * (index + 1), 0]; - - return <> - {Interface.___any.stats ? : <>} - - - - {/*{Interface.___any.Ray.map((ray: Ray.Any) => )}*/} - - {Interface.___any.Ray.map((ray: Ray.Any) => )} - - - - - {Interface.___any.Ray.map((ray: Ray.Any, index: number) => )} - - - - - - - {Interface.___any.Ray.map((ray: Ray.Any, index: number) => )} - - - - {/**/} - {/* {[*/} - {/* Ray.vertex().o2({*/} - {/* initial: { position: [(-space_between / 1.5) - (space_between / 1.5) * 2, -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* vertex: { index: 0, position: [0 - (space_between / 1.5) * 2, -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* terminal: { position: [(space_between / 1.5) - (space_between / 1.5) * 2, -140, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} - {/* }),*/} - {/* Ray.vertex().o2({*/} - {/* initial: { position: [(-space_between / 1.5) + (space_between / 1.5) * 2, -120, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* vertex: { index: 0, position: [0 + (space_between / 1.5) * 2, -120, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* terminal: { position: [(space_between / 1.5) + (space_between / 1.5) * 2, -120, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} - {/* }),*/} - {/* Ray.vertex().o2({*/} - {/* initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* vertex: { index: 0, position: [0, -120, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* terminal: { position: [(space_between / 1.5), -120, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} - {/* }),*/} - {/* Ray.vertex().o2({*/} - {/* initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* vertex: { index: 0, position: [0, -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* terminal: { position: [(space_between / 1.5), -120, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} - {/* }),*/} - {/* Ray.vertex().o2({*/} - {/* initial: { position: [(-space_between / 1.5), -140, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* vertex: { index: 0, position: [0, -160, 0], scale: scale / 1.5, color: '#FF5555' },*/} - {/* terminal: { position: [(space_between / 1.5), -160, 0 ], scale: scale / 1.5, color: '#FF5555' },*/} - {/* }),*/} - {/* ]*/} - {/* .flatMap(ray => [ray.initial.as_reference(), ray.as_reference(), ray.terminal.as_reference()])*/} - {/* .map(ray => )*/} - {/* }*/} - {/* /!**!/*/} - {/* /!**!/*/} - {/**/} - -} - -export const DebugInterface3 = ({scale = 1.5}: InterfaceOptions) => { - const ref = useRef(); - const hotkeyConfig = useHotkeys(); - - const { - gl: renderer, - camera, - scene, - raycaster - } = useThree(); - - const space_between = 20 * scale; - - const [Interface] = useState(Ray.vertex().o({ - selection: Ray.Any.vertex().o2({ - initial: { position: [-space_between, 0, 0], scale, color: 'orange' }, - vertex: { index: 0, position: [0, 0, 0], scale, color: 'orange' }, - terminal: { position: [space_between, 0, 0 ], scale, color: 'orange' }, - }).as_reference().o({ - position: [0, 0, 0], - scale, - rotation: [0, 0, Math.PI / 6 ], - color: '#555555' - }), - rays: [] as Ray[], - stats: false, - cursor: { - tick: false - }, - controls: { - hotkeys: [ - { - combo: ["d", "arrowright"], global: true, label: "", onKeyDown: () => { - const { selection, rays } = Interface.___any; - - const current = Interface.___any.selection.render_options(Interface); - - const next = Ray.vertex().o2({ - initial: { position: add_(current.position, [(space_between * 2) - space_between, 0, 0]), scale, color: 'orange' }, - vertex: { index: Interface.___any.selection.___any.index + 1, position: add_(current.position, [(space_between * 2), 0, 0]), scale, color: 'orange' }, - terminal: { position: add_(current.position, [(space_between * 2) + space_between, 0, 0 ]), scale, color: 'orange' } - }).as_reference().o({ - ...selection.as_reference().render_options(Interface), - position: add(selection.___any.position ?? [0, 0, 0], [space_between * 2, 0, 0]) - }); - - Interface.___any.selection = selection.compose(next); - Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray.Any) => { - ray.___any.traversed = true; - return ray.as_reference(); - }); - - } - }, - { - combo: ["a", "arrowleft"], global: true, label: "", onKeyDown: () => { - if (Interface.___any.Ray.length === 0) - return; - - Interface.___any.selection = Interface.___any.selection.pop(); - Interface.___any.selection.o({ - position: Interface.___any.selection.render_options(Interface).position - }); // TODO, Same with this. - Interface.___any.selection.self.terminal.o({ - position: add(Interface.___any.selection.render_options(Interface).position, [space_between, 0, 0]), scale, color: 'orange' - }); // TODO: The continues_with function doesn't persist the options, as they are ignored on the equivalency. Probably need some better way to deal with this kind of thing. - - Interface.___any.rays = Interface.___any.selection.self.___dirty_all([]).map((ray: Ray.Any) => { - ray.___any.traversed = true; - return ray.as_reference(); - }); - - if (Interface.___any.length === 0) { - Interface.___any.selection.___any.position = [0, 0, 0] - return; - } - } - }, - { - combo: ["w", "arrowup"], global: true, label: "", onKeyDown: () => { - const { selection, rays } = Interface.___any; - - Interface.___any.rays = Ray.flatMap((ray: Ray.Any) => [ - ray, - // Ray.js("A").as_reference().o({ - // // ...ray.o, - // position: add(ray.___any.position ?? [0, 0, 0], [0, i * 2, 0]) - // }), - // Ray.js("A").as_reference().o({ - // // ...ray.o, - // position: Ray.Any.___any.position, - // rotation: [0, 0, Math.PI / 2] - // }), - // Ray.js("A").as_reference().o({ - // // ...ray.o, - // position: add(ray.___any.position ?? [0, 0, 0], [0, i * 2, 0]), - // rotation: [0, 0, Math.PI / 2] - // }) - ]); - - // Chyp_naieve_pass.___any.selection = Chyp_naieve_pass; - - // selection.o({...selection.o, position: add(selection.___any.position ?? [0, 0, 0], [0, i * 2, 0])}) - - // selection.compose( - - // ); - } - }, - { - combo: "/", global: true, label: "", onKeyDown: () => { - console.log('---------') - console.log(`Debugging: ${Interface.___any.selection.self.label} (type=${Interface.___any.selection.type})`) - console.log(`Ray.length at pos=[${Interface.___any.selection.render_options(Interface).position}]: ${Interface.___any.Ray.filter((ray: Ray.Any) => - _.isEqual( - Interface.___any.selection.render_options(Interface).position, - ray.render_options(Interface).position - ) - ).length} / ${Interface.___any.Ray.length}`) - console.log('ref', Interface.___any.selection) - console.log('ref.self', Interface.___any.selection.self) - - const debug: DebugResult = {}; - Interface.___any.selection.self.debug(debug); - console.log('ref.debug', debug); - Interface.___any.Ray.forEach((ray: Ray.Any) => Ray.Any.debug(debug)); - console.log('Ray.debug', debug); - } - }, - { - combo: "f3", global: true, label: "Show stats Panel", onKeyDown: (e) => { - e.preventDefault(); - Interface.___any.stats = !Interface.___any.stats; - } - }, - ] as HotkeyConfig[] - } - })); - - // useEffect(() => { - // TODO: Eventually goes over maximum size of react-debug callstack when updates each frame like this. - hotkeyConfig.set(...Interface.___any.controls.hotkeys); - // }, [Interface.___any.controls.___any.hotkeys]); - - useEffect(() => { - - setInterval(() => { - Interface.___any.cursor.tick = !Interface.___any.cursor.tick; - - // TODO THIS NEEDS TO BE EASIER - }, 500); // TODO; On react reload interval is not destroyed - }, []); - - return <> - {Interface.___any.stats ? : <>} - - - - {Interface.___any.Ray.map((ray: Ray.Any) => )} - -} - -// const Interface = () => { -// // TODO: Direct call to rerender on change, now there's lag -// -// const Rendered = ({ ray, ...options }: { ray: Ray.Any } & InterfaceOptions) => { -// const { position = options.position, rotation = options.rotation, scale = options.scale, color = options.color } = ray.___any; -// return ; -// } -// -// const DEBUG = true; -// -// const debug: DebugResult = {}; -// selection.debug(debug); -// -// return <> -//
-// {/**/} -// {/**/} -// {/**/} -// -// {/**/} -// -// {/**/} -// {/**/} -// -// -// -// {Ray.map((ray: Ray.Any) => )} -// -// {/**/} -//
-// -// } - -/** - * TODO: Import .chyp files - * TODO: Export to .chyp files - */ -const ChypCanvas = ( - { - listeners = [], - }: { - listeners?: IEventListener[], - } -) => { - const listener: IEventListener = { - - } - - return
- {/**/} - {/* */} - {/* */} - {/**/} - - - - -
-} - -export const ChypExplorer = ( - { - listeners = [], - }: { - listeners?: IEventListener[], - } -) => { - - const listener: IEventListener = {} - - return -} - -export default ChypCanvas; \ No newline at end of file diff --git a/orbitmines.com/src/@orbitmines/external/chyp/Chyp_naive_pass.ts b/orbitmines.com/src/@orbitmines/external/chyp/Chyp_naive_pass.ts deleted file mode 100644 index 52d3057..0000000 --- a/orbitmines.com/src/@orbitmines/external/chyp/Chyp_naive_pass.ts +++ /dev/null @@ -1,1665 +0,0 @@ -// import {JS, Ray} from "../../explorer/Ray"; -// import {NotImplementedError} from "../../explorer/errors/errors"; -// -// /** -// * - The .copy()'s are implemented on Ray. -// * -// * TODO: There's a lot of duplicate code, unnecessary documentation and non-generality in Chyp. It was probably developed as a proof of concept? - Expecting that to be addressed in the projects Aleks Kissinger is currently setting up. -// * -// * TODO: Probably want all these types at runtime, to display them -// * -// * TODO: Graph boundary is automatic with this structure? -// * -// * TODO: merging vertex, just drawinf that one equivalence between initial/terminal etc..?? just leave the vertex? -// * -// * TODO: Methods, files, as wealonry selectuon along some linez simple name above, .. -// * -// * TODO: Can just move the terminal which holds the oointer to the boundary -// * -// * TODO: Automatically generate visual examples of all the methods -// * -// * TODO: Runtime errors as rays -// * -// * TODO: All the more complicated methods should be simply implemented in a ray which walks an arbitary graph -// */ -// /** -// * TODO: These coordinates used for inferences? -// * - If not then this is probably a hack and should be interpreted as "on another layer of description which is the GUI" -// */ -// -// export const int = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const list = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const Iterable = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const set = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const str = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QKeyEvent = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const Optional = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const Tuple = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QObject = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const Union = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QModelIndex = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QPersistentModelIndex = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QWidget = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const List = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const Qt = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const Orientation = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QPainter = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QStyleOptionGraphicsItem = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const bool = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const False = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const True = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QGraphicsSceneMouseEvent = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QTextDocument = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const editor = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const QCloseEvent = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const Any = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const tuple = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const None = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const state = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const Callable = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// export const Set = (t1?: any, t2?: any, t3?: any): Ray.Any => { throw new NotImplementedError() }; -// -// export const Color = (t1: Ray.Any = str('')): Ray.Any => { throw new NotImplementedError() }; -// -// export class ValueError extends Error {} -// -// /** -// * Non-default vertex types are identified by a string label -// * -// * str() | None() - No overloading in TypeScript ;( -// */ -// export const VType = JS.Iterable([str, None]); -// -// /** -// * Used for debugging (the matcher) -// */ -// const DEBUG = true; // TODO; Generalize -// const log = (s: string) => { -// if (!DEBUG) -// return; -// -// console.log(s); -// } -// -// /** -// * Data associated with a single vertex. -// */ -// export class VData extends Ray { -// // The vertex type. -// vtype = this.property('vtype', None); -// -// // The register size (number of bundled parallel wires) of the vertex. -// size = this.count; // Implemented on Ray.count -// -// // TODO: These infers will probably be removed? -// // Whether to infer the vertex type during composition. Used for special generators (identities, permutations, redistributers). -// infer_type = this.property('infer_type', bool(False)) -// // Whether to infer the vertex size during composition. Used for special generators (identities, permutations, redistributers). -// infer_size = this.property('infer_size', bool(False)) -// -// // x-coordinate at which to draw the vertex. -// x = this.property('y', int(0)) -// // y-coordinate at which to draw the vertex. -// y = this.property('y', int(0)) -// -// highlight = this.property('highlight', bool(False)) -// value = this.property('value') -// -// /** -// * Indices (if any) where this vertex occurs in the input and output lists of the hypergraph. -// */ -// get in_indices(): Ray.Any { return this.initial } // -// get out_indices(): Ray.Any { throw new NotImplementedError(); } -// -// is_input = (): Ray.Any => this.in_indices.count.as_int() > 0; -// is_output = (): Ray.Any => this.out_indices.count.as_int() > 0; -// is_boundary = (): Ray.Any => this.is_input() || this.is_output(); -// -// // TODO: Probably generalizable -// -// /** -// * Form the quotient of the graph by identifying v with w. Afterwards, the quotiented vertex will be have integer identifier `v`. -// * -// * TODO; particular sort of composing -// */ -// merge = (other: VData): Ray.Any => { -// throw new NotImplementedError(); -// } -// -// fresh = (): VData => { -// // TODO: This is just a copy where this initial/terminal directionlaity is ignored. Only a copy of the vertex. -// -// // vtype=vd.vtype, size=vd.size, -// // x=vd.x, y=vd.y, value=vd.value -// -// } -// -// // TODO: Shouldn't be here, this should be implemented on Ray if it's general enough -// get domain(): Ray.Any { return JS.Iterable([this.vtype, this.size]) }; -// -// } -// -// export class EData extends Ray { -// -// fg = this.property('bg', Color()); -// bg = this.property('bg', Color()); -// x = this.property('y', int(0)); -// // y-coordinate at which to draw the vertex. -// y = this.property('y', int(0)); -// highlight = this.property('highlight', bool(False)) -// hyper = this.property('value', bool(True)) -// value = this.property('value') -// -// __repr__ = (): Ray.Any => { throw new NotImplementedError(); -// // TODO: return f'Edge: {self.value} ({self.x}, {self.y})' -// } -// -// // TODO: More stuff to relate it to the screen that shouldnt be here. -// /** -// * Return how many width 'units' this box needs to display nicely. -// * -// * This uses a simple rule: -// * - If the number of inputs and outputs are both <= 1, draw as a small (1 width unit) box. -// * - Otherwise draw as a larger (size 2) box. -// */ -// box_size = (): Ray.Any => JS.Number((this.s.count.as_int() <= 1 && this.t.count.as_int() <= 1) ? 1 : 2); -// -// domain = (): Ray.Any => this.source.cast().domain; -// codomain = (): Ray.Any => this.target.cast().domain; -// -// toString = (): string => this.__repr__().as_string(); // TODO; FOR ALL -// } -// -// /** -// * A hypergraph with boundaries. -// * -// * This is the main data structure used by Chyp. It represents a directed -// * hypergraph (which we call simply a "graph") as two dictionaries for -// * vertices and (hyper)edges, respectively. Each vertex is associated with a -// * `VData` object and edge edge with an `EData` object, which stores -// * information about adjacency, position, label, etc. -// * -// * The particular flavor of hypergraphs we use associate to each hyperedge a -// * list of source vertices and a list of target vertices. The hypergraph -// * itself also has a list of input vertices and a list of output vertices, -// * which are used for sequential composition and rewriting. -// */ -// export class Graph extends Ray { -// -// get vindex(): Ray.Any { return this.vdata.index.max(0); } -// get eindex(): Ray.Any { return this.edata.index.max(0); } -// -// // Mapping from integer identifiers of each vertex to its data. -// vdata = this.property('vertices'); -// // Mapping from integer identifiers of each hyperedge to its data. -// edata = this.property('edges'); -// -// // TODO .keys -// vertices = this.property('vertices'); -// edges = this.property('edges'); -// -// /** -// * Return the domain of the graph. -// * -// * This consists of a list of pairs (vertex type, register size) corresponding to each input vertex. -// */ -// // TODO: Domain/Codmain is just the initial/terminal side (possibly typed) where the direction which is what defines what it itself is connected to, is ignored. -// get domain(): Ray.Any { return this.inputs.cast().domain; }; -// -// /** -// * Return the domain of the graph. -// * -// * This consists of a list of pairs (vertex type, register size) corresponding to each output vertex. -// */ -// get codomain(): Ray.Any { return this.outputs.cast().domain; }; -// -// vertex_data = (v = int): VData => this.vertices().at(v).cast(); -// edge_data = (e = int): EData => this.edges().at(e).cast(); -// -// // TODO: Shouldnt be here -// ___next_index = (name = int(-1), index: Ray.Any): Ray.Any => { -// // TODO: This is definitely going to be buggy if '-1' and certain specific values are used. (Hence the note above add_vertex & add_edge) -// const current = name === -1 ? index : Math.max(name, index); -// return current + 1; -// } -// -// /** -// * Add a new vertex to the graph. -// * -// * @param name The value carried by this vertex (currently unused). -// * TODO: Generally this is just additional structure at the vertex, rays just implement this generally. -// * @param vertex The integer identifier to use for this vertex. If this is set to -1, the identifier is set automatically. (Note: no checks are currently made to ensure the identifier is not already in use). -// */ -// add_vertex = (name = int(-1), vertex: VData): VData => { -// this.vindex = this.___next_index(name, this.vindex); -// -// this.vdata[this.vindex - 1] = vertex; -// return vertex; -// } -// -// /** -// * Add a new hyperedge to the graph. -// * -// * @param s -// * @param t -// */ -// add_edge = (name = int(-1), edge: EData): EData => { -// this.eindex = this.___next_index(name, this.eindex); -// -// this.edata[this.eindex - 1] = edge; -// -// // TODO: Syncs the initial/terminal to the vertices (basically non-ignorant connection) -// // for v in s: -// // self.vdata[v].out_edges.add(e) -// // for v in t: -// // self.vdata[v].in_edges.add(e) -// -// return edge; -// } -// // add_simple_edge - is automatically handled: Ray.Anys can disambiguate between one/multiple values for certain purposes. -// -// /** -// * Remove a vertex from the graph. -// * -// * This removes a single vertex. -// * - If `strict` is set to True, then the vertex must have no adjacent edges nor be a boundary vertex. -// * - If `strict` is False, then `v` will be removed from the source/target list of all adjacent edges and removed from the boundaries, if applicable. -// * -// * @param v -// * @param strict If True, require the vertex to have no adjacent edges and not be a boundary vertex. -// */ -// remove_vertex = (v = int, strict: boolean = false): Ray.Any => { -// // TODO: as delegation -// -// if (strict) { -// if (this.vertex_data(v).in_edges.count.as_int() > 0 || this.vertex_data(v).out_edges > 0) { -// throw new ValueError('Attempting to remove vertex with adjacent' -// + 'edges while strict == True.'); -// } -// -// if (this.inputs.includes(v) || this.outputs.includes(v)) { -// throw new ValueError('Attempting to remove boundary vertex while' -// + 'strict == True.'); -// -// }// TODO CAN BE SIMPLIFIED -// } -// -// // in/out edges from all vertices -// delete this.vdata[v]; -// } -// -// /** -// * Remove an edge from the graph. -// * -// * @param e Integer identifier of the edge to remove. -// */ -// remove_edge = (e = int): Ray.Any => { -// // in/out edges from all vertices -// delete this.edata[e]; -// } -// -// // TODO: Can these be overlaoded in properties using -=, += in TS? -// -// -// -// -// // TODO: These are just one possibly ignorant ray through the initial/terminal ends which aren't matched - could just generate these on the fly, or similar to chyp add when added. -// -// -// -// // set function: -// // TODO: Clears the matched in/out indices, then sets them to the ones found in in/outputs -// // inputs =, outputs = -// // for the add functions: // TODO: Perhaps splat -// // also for add // TODO; these are then again duplicated to self.vdata[v].out_indices.add(i) -// -// -// /** -// * Return vertices that lie on a directed path from any of `vs`. -// * // TODO: Just traverse the rays, deduplicate using the index -// */ -// successors = (ray: Ray.Any): Ray.Any => Ray.Any.next; -// -// /** -// * Split a vertex into copies for each input, output, and tentacle. -// * -// * This is used for computing pushout complements of rules that aren't left-linear. -// * (See arXiv:2012.01847 Section 3.3 for definition of left-linear). -// * -// * Returns: A pair of lists containing the new input-like and output-like vertices, respectively. -// * -// * @param v Integer identifier of vertex to be exploded. -// */ -// explode_vertex = (v = int): Ray.Any => { -// const vertex = this.vertex_data(v); -// -// // TODO; This just seems like another copy which minor changes -// -// const next_inputs = empty(); -// const next_outputs = empty(); -// -// const __temp = ( // TODO This whole bit of code will definitely be reduced to one line at some point in this process -// vertex: VData, -// boundary: (vertex: VData) => Ray.Any, -// next_boundary: Ray.Any -// ) => { -// // TODO: It's just a duplicated process for vertex/edge since their definition is separataed -// -// // Replace any occurrences of the original vertex in the graph inputs with a new input-like vertex. -// // self.set_inputs([v1 if v1 != v else fresh(0) for v1 in self.inputs]) -// // TODO: Basically a copy, and replace this one vertex -// -// // Where the original vertex is the target of a hyperedge, replace its occurrence in the hyperedge's target list with a new input-like vertex and register this with the new vertex's data instance. -// boundary(vertex).all(e => { -// const edge: EData = e.cast(); -// -// edge.t = edge.t -// .map(target => { -// if (target === v) -// return target; -// -// const fresh_vertex = vertex.fresh(); -// next_boundary.add(this.add_vertex(fresh_vertex)) -// boundary(fresh_vertex).add(edge); -// }) -// }); -// -// } -// -// // TODO: It's always just duplicated for both ends, -// __temp(vertex, (vertex) => vertex.in_edges, next_inputs); -// __temp(vertex, (vertex) => vertex.out_edges, next_outputs); -// -// // Register the fact that `v` no longer occurs in as a source or target of any hyperedge. -// vertex.in_edges.clear(); // TODO; Should basically just reset initial/terminal -// vertex.out_edges.clear(); -// -// // Remove `v` from the hypergraph, using strict == True to catch any errors (no errors should be raised with current code). -// this.remove_vertex(vertex, true); -// -// return [next_inputs, next_outputs]; -// } -// -// -// /** -// * Insert a new identity hyperedge after the given vertex. -// * -// * A new vertex is also created, which replaces the original vertex as the source of any edges in graph as well as any occurrences of the original vertex in the graph outputs. -// * -// * @param reverse -// * - If `False`, the original vertex becomes the source of the ew identity hyperedge while the new vertex becomes the target. -// * - If `True`, the source and target of the new identity are flipped. This can be used to break directed cycles, by neffectively introducing a cap and cup. -// */ -// insert_id_after = (v = int, reverse = bool(False)): Ray.Any => { -// const vertex = this.vertex_data(v); -// -// // Create a new vertex with the same vtype and size -// // //TODO ; Which is this .fresh -// const new_vertex = vertex.fresh(); -// new_vertex.x += 3; -// // The new vertex is highlighted whenever the orignal vertex is. -// new_vertex.highlight = vertex.highlight; // TODO: This not done by .fresh? -// -// /** -// * //TODO: BEcause it's inserted after, set the output (generalize to just moving the reference to the terminal. -// * # Replace any occurences of the original vertex in the graph outputs -// * # with the new vertex. -// * self.set_outputs([x if x != v else w for x in self.outputs()]) -// */ -// -// // Where the original vertex is the source of a hyperedge, replace it with the new vertex and register this change with the data instance of each vertex -// // TODO syncs the out_edges fields, wd.out_edges.add(e) vd.out_edges.clear() -// // TODO replace out_edges.source to new_vertex again -// -// // Assign the orignal and new vertex as source or target of the new identity edge, based on the `reverse` argument. -// // TODO: Sets reverse just flipping around the initial/terminal.. -// // TODO: s, t = ([v], [w]) if not reverse else ([w], [v]) -// -// // Create the new identity edge. -// const edge = this.add_edge() // s, t, 'id', vd.x + 1.5, vd.y) -// edge.hightlight = vertex.highlight; // The new edge is highlighted whenever the original vertex is. -// -// return edge; -// } -// -// /** -// * Take the monoidal product of this graph in-place with another. -// * -// * Calling g.tensor(h) will turn g into g ⊗ h, performing the operation in-place. Use the infix version `g @ h` to simply return the tensor product without changing g. -// * -// * @param other -// * @param layout If `True`, compute new y-coordinates of the vertices and edges of the resulting graph so that the two graphs in the tensor product are adjacent with no overlap in the y-direction. -// */ -// tensor = (other: Graph, layout: boolean = true): Ray.Any => { -// -// const a = this; -// const b = other; -// -// const tensor: Ray.Any = new Ray(); // TODO: [initial = a.outputs, terminal = b.inputs] -// -// tensor.initial.any.y -= -// tensor.initial.any.y.max(); // max_self -// -// tensor.terminal.any.y -= -// (layout ? tensor.terminal.any.y.min() : 0) + 1; // min_other TODO: Why + 1 ? -// -// /** -// * # self.set_inputs(self.inputs + [vmap[v] for v in other.inputs]) -// * # self.set_outputs(self.outputs + [vmap[v] for v in other.outputs]) -// * -// * # Add the inputs and outputs of the other graph to this one. -// * self.add_inputs([vmap[v] for v in other.inputs]) -// * self.add_outputs([vmap[v] for v in other.outputs]) -// */ -// // TODO: Add equivalence/reference on the inputs/output extremes. -// } -// -// -// // Merge = compose.. -// // /** -// // * Compose structures defined at .initial with those at .terminal, dropping the vertex. ; or if done non-ignorantly. Composing them on another level, ignoring to this vertex. TODO: Allow this freedom -// // */ -// // get merge(): Ray.Any { -// // // concat initial.a + initial.b, terminal.a + terminal.b -// // // then: either destroy a/b, merge structure... etc.. -// // // Chyp: destroy b -// // -// // // this.initial.equivalent(other.initial); -// // // this.terminal.equivalent(other.terminal); -// // -// // /* -// // -// // vd = self.vertex_data(v) -// // # print("merging %s <- %s" % (v, w)) -// // -// // # Where vertex `w` occurs as an edge target, replace it with `v` -// // for e in self.in_edges(w): -// // ed = self.edge_data(e) -// // ed.t = [v if x == w else x for x in ed.t] -// // vd.in_edges.add(e) -// // -// // # Where vertex `w` occurs as an edge source, replace it with `v` -// // for e in self.out_edges(w): -// // ed = self.edge_data(e) -// // ed.s = [v if x == w else x for x in ed.s] -// // vd.out_edges.add(e) -// // -// // # Wherever `w` occurs on the graph boundary, replace it with `v` -// // self.set_inputs([v if x == w else x for x in self.inputs]) -// // self.set_outputs([v if x == w else x for x in self.outputs]) -// // -// // # Remove references to `w` from the graph -// // self.remove_vertex(w) -// // -// // */ -// // throw new NotImplementedError(); -// // } -// -// -// // @alias('merge') ?? TODO -// // static compose = Ray.___func(ref => { -// // const { initial, terminal } = ref.self; -// // -// // return initial.___primitive_switch({ -// // [RayType.VERTEX]: () => { -// // const vertex = initial.self; -// // -// // // TODO; Implement as restrictive case for Chyp -// // { -// // // if (this.self.initial.count.as_int() !== this.terminal.count.as_int()) -// // // throw new NotImplementedError(`Initial (Graph.Domain) does not match Terminal (Graph.Codomain)`); -// // -// // // Check that codomain of this graph matches the domain of the other: this is required for valid sequential composition. -// // // if (this.self.initial.is_equivalent(this.self.terminal)) -// // // throw new NotImplementedError('Initial (Graph.Domain) does not match Terminal (Graph.Codomain) types.'); // TODO; Should take care of vtype/size matches at input/output -// // } -// // -// // /** -// // * A simple case of what we want to solve here. -// // * -// // * Initial Terminal -// // * ... ... -// // * [--| ] [ |--] -// // * [--| ] [ |--] -// // * [--| ] [ |--] -// // * [ |--] [--|--] [--| ] -// // * vertex -// // * -// // * And recursively (arbitrarily) match initial/terminal structures. -// // */ -// // -// // throw new NotImplementedError(); -// // } -// // }) -// // }); -// // compose = Ray.compose(this); -// -// /** -// * Sequentially compose this graph in-place with another. -// * -// * Calling g.compose(h) will turn g into g ; h, performing the operation in-place. Use the infix version `g >> h` to simply return the sequential composition without changing g. -// */ -// compose = (other: Graph): Ray.Any => { -// // TODO Just matching outputs and inputs.. -// -// // TODO: Simply visualized, as a single thing "us composing this thing", where on the initial side, we have the outputs of one thing, which we're trying to one-to-one match to the terminal side" -// -// // TODO: min/max needs to be on vertices/edges. Not necessarilyt outputs/inputs -// -// /** -// * Basically, seeing the {compose} line x=0, and them moving outputs (left) to the negative x. And moving the inputs (right) to the positive x. -// */ -// -// // Compute the max x-coordinate of the edges and vertices in this graph. -// -// // TODO: Again, recursively going through everything defined on the initial side (outputs) -// // Shift all vertices and edges of this graph below the x-axis. -// compose.initial.any.x -= -// compose.initial.any.x.max(); // max_self -// -// // TODO: It's indeed copying here, as b_copy, abstract this away [SHOULD BE A COPY] -// compose.terminal.any.x -= -// compose.terminal.any.x.min(); // min_other -// -// // TODO: This check in the Chyp code is just done after the [terminal].copy() which we haven't implemented yet. -// /** -// * plug1 = self.outputs -// * plug2 = [vmap[v] for v in other.inputs] -// * -// * if len(plug1) != len(plug2): -// * raise GraphError(f'Attempting to plug a graph with {len(plug1)} ' -// * + f'outputs into one with {len(plug2)} inputs') -// * -// * self.set_outputs([vmap[v] for v in other.outputs]) -// */ -// -// // [outputs to inputs] -// // Go through pairs of vertices from each plug -// compose.zip().all(([input, output]) => { -// /** -// * While vertex currently assigned to p1 has already been merged into another vertex, repeatedly replace it with the vertex it was merged into until p1 is a vertex that has not already been merged. Vice versa for p2. -// */ -// -// // TODO: does this ever happen??? -// // while p1 in quotient: -// // p1 = quotient[p1] -// // while p2 in quotient: -// // p2 = quotient[p2] -// -// -// // TODO, Again the same equivalence check for loops etc.. -// { -// // If the resulting p1 and p2 are not the same vertex, merge them. -// if (input === output) -// return; -// -// // TODO; DO this on the vertices; -// // data_1 = self.vertex_data(p1) data_2 = self.vertex_data(p2) -// -// // If both vertices have flexible types that are not equal, raise an error due to ambiguity. -// // TODO: Basically, if we're assuming there could be ignorance here, which we wouldn't do on the types. Again, the types necessarily have ambiguity as well, it's just ignored in that instance. -// -// -// // TODO: From here assumes same types, now just checking size (size should again be generalized to type), it's just structure. -// -// ['vtype', 'size'].forEach(structure => { -// const infer = `infer_${structure}`; -// -// if (input[infer] && output[infer] && input[structure] !== output[structure]) { -// throw GraphError(`Ambiguous vertex ${structure} during composition.`) -// -// } else if (input[infer]) { -// // Otherwise, if one vertex has a flexible type, ensure the vertex types match. -// // TODO: Infer type = true, basically means, ignorant ambiguous type, which will just change to whatever it matched to it -// // TODO: Again both sides same thing.. -// input[structure] = output[structure]; // TODO: Generalized structure -// input[infer] = false; -// } else if (output.infer_type) { -// output[structure] = input[structure]; -// output[infer] = false; -// } -// }); -// -// input.merge(output); -// // # Register than p2 has been merged into p1. -// // quotient[p2] = p1 -// } -// }); -// } -// -// /** -// * Return the tensor product of this graph with another. -// * -// * This does not modify either of the original graphs. TODO: Again this sort of thing should be abstracted elsewhere on what to do with them -// */ -// __mul__ = (other: Graph): Ray.Any => this.___something_something_copy(other, (a, b) => a.tensor(b)); -// -// /** -// * Return the composition of the current graph with `other`. -// * -// * Composition is done in diagram order (`other` comes after `self`), and neither of the two graphs are modified. -// * @param other -// */ -// __rshift__ = (other: Graph): Ray.Any => this.___something_something_copy(other, (a, b) => a.compose(b)); -// -// /** -// * TODO: These are just simple delegations of a single method on copies.. ; requires a nice abstraction layer -// */ -// ___something_something_copy = (b: Graph, something: (a: Graph, b: Graph) => void): Ray.Any => { -// const a_copy: Graph = this.copy().cast(); // TODO: Here preferring copy, do this everywhere? / Depending on forgetful preference.. -// something(a_copy, b); // TODO: Chyp just assumes b to be copied at the other end here??? -// return a_copy; // Could generalize to either end -// } -// -// /** -// * Set the `highlight` flag for a set of vertices and edges. -// * -// * This tells the GUI to visually highlight a set of vertices/edges, e.g. by drawing them in bold. Any vertices/edges not in the sets provided will be un-highlighted. -// * -// * @param vertices A set of vertices to highlight. -// * @param edges A set of edges to highlight. -// */ -// highlight = (vertices = set(int), edges = set(int)): Ray.Any => { -// // TODO Again, these could be merged -// this.vdata -// .filter(vertex => vertices.includes(vertex)) -// .all(vertex => vertex.cast().highlight = bool(true)); -// this.edata -// .filter(edge => edges.includes(edge)) -// .all(edge => edge.cast().highlight = bool(true)); -// -// } -// -// /** -// * Clear the `highlight` flag for all vertices/edges. -// * -// * This is equivalent to calling :func:`highlight` with empty sets of vertices/edges. -// */ -// unhighlight = (): Ray.Any => { -// // TODO: These could be merged -// this.vdata.highlight = false; -// this.edata.highlight = false; -// } -// -// /** -// * Return matches of domain into codomain. -// */ -// match = (other: Graph, convex: boolean = true): Matches => new Matches(this, other, convex); -// -// /** -// * Return an isomorphism between graphs g and h if found, otherwise `None`. -// * -// * If found, the isomorphism is returned as a :py:class:`Matches` instance, whose vertex and edge maps are bijections. -// */ -// find_iso = (other: Graph): Match => { // TODO | NONE -// -// // TODO: Again, more equivalence checks -// // First, check the domains and codomains are equal between the two graphs. -// if (this.domain !== other.domain || this.codomain !== other.codomain) -// return None; //TODO -// -// // Try to find an initial match mapping one of the boundary vertices of the domain graph to the corresponding boundary vertex (the vertex in the same input/output location) of the codomain graph. If no initial match is found, return `None`. -// const initial_match = new Match(this, other); -// -// const ___temp = (func: (ray: Graph) => Ray.Any) => { -// ([func(this), func(other)] as Ray).zip(([initial, terminal]) => { -// if (!initial_match.try_add_vertex(initial, terminal)) -// return None; //TODO, DOESNT ACTUALLY RETURN THE FUNCTION HERE. Wait till matcher is abstracted to fix this -// }); -// } -// -// ___temp(ray => Ray.Any.inputs); -// ___temp(ray => Ray.Any.outputs); // TODO: See again, the same pattern over and over again, same on both sides. -// -// // If an initial match is found, try to find a total and surjective match of the domain graph into the codomain graph. -// -// return new Matches(this, other, initial_match, false) -// .filter(match => match.is_surjective()); // TODO; With this filter it should allow you to keep looking -// -// // TODO::: Automatic?? -// // If a total surjective match is not found, return `None`. -// return None; -// } -// } -// -// export class Chyp extends Ray { -// __init__ = (): Ray.Any => { throw new NotImplementedError(); } -// -// /** -// * Load a .chyp graph file from the given path. -// */ -// load_graph = (path = str) => { -// // TODO: From localStorage for now? -// // with open(path) as f: -// // g = graph_from_json(f.read()) -// } -// -// /** -// * Return a graph corresponding to the identity map. -// * -// * This graph has a single vertex which is both an input and an output. -// */ -// identity = (vertex: VData): Graph => { -// const graph = new Graph(); -// -// vertex.x = 0; // TODO automatic>? -// vertex.y = 0; -// graph.add_vertex(int(-1), vertex); -// // TODO synce input/output automatically? -// // g.set_inputs([v]) -// // g.set_outputs([v]) -// -// return graph; -// } -// -// -// ___map_domain = (domain: Ray.Any, _default: VData): Ray.Any => { -// return domain.map(([vtype, size], i) => { -// const vertex: VData = _default.copy().cast(); -// // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere -// vertex.x = -1.5; -// vertex.y = i - (i-1) / 2; -// -// return vertex; -// }) -// } -// -// /** -// * Return a graph with one hyperedge and given domain and codomain. -// * -// * @param _default -// * @param domain - A list of pairs (vertex type, register size) corresponding to each input vertex. -// * @param codomain - A list of pairs (vertex type, register size) corresponding to each output vertex. -// */ -// gen = (_default: VData, domain: Ray.Any, codomain: Ray.Any): Graph => { -// const graph = new Graph(); -// -// const inputs = this.___map_domain(domain, _default) -// .map(vertex => graph.add_vertex(vertex)); -// const outputs = this.___map_domain(codomain, _default) -// .map(vertex => graph.add_vertex(vertex)); -// -// // TODO This is probably automatic at some point, remove -// const edge = new EData(); -// edge.s = inputs; -// edge.t = outputs; -// graph.add_edge(int(-1), edge); -// // g.set_inputs(inputs) -// // g.set_outputs(outputs) -// -// return graph; -// } -// -// /** -// * Return a graph corresponding to the given permutation. -// * -// * This takes a permution, given as a list [x0,..,x(n-1)], which is interpreted as the permutation { x0 -> 0, x1 -> 1, ..., x(n-1) -> n-1 }. It produces a graph consisting just of vertices, where input xj is mapped to the same vertex as output j, representing an identity wire connecting input xj to output j. -// * -// * Note this is one of two reasonable conventions for specifying a permutation as a list of numbers. This one has the property, e.g. for graphs aj : 0 -> 1, we have: (a0 * a1 * a2) >> perm([2, 0, 1]) = a2 * a0 * a1. -// * -// * @param p A permutation given as an n-element list of integers from 0 to n-1. -// * @param domain The domain type of the permutation. This consists of a list of pairs (vertex type, register size) corresponding to each input vertex of the edge. If `None`, the domain is assumed to be the appropriate number of default type vertices all with register size 1. -// */ -// perm = (p = list(int), domain: Ray.Any, _default: VData) => { -// -// const graph = new Graph(); -// const num_wires = p.count.as_int(); -// -// if (num_wires !== domain.count.as_int()) -// throw new GraphError(`Domain ${domain} does not match length of permutation.`) -// -// // TODO use ___map_domain -// const inputs = domain.map(([vtype, size], i) => { -// const vertex: VData = _default.copy().cast(); -// // TODO: These should be automatic somewhere, again abstract the place where it's displayed elsewhere -// vertex.x = 0; -// vertex.y = i - (num_wires - 1) / 2; -// -// return vertex; -// }) -// .map(vertex => graph.add_vertex(vertex)); -// // const outputs = num_wires.range(i => [inputs[p[i]]) -// -// // TODO Should be automatic -// // g.set_inputs(inputs) -// // g.set_outputs(outputs) -// return graph; -// } -// -// graph_from_json = (json_string = str): Graph => { -// const json = JSON.parse(json_string().as_string()); // TODO -// -// const graph = new Graph(); -// -// // TODO: Don't do this so naively -// // g.add_vertex(x=float(vd["x"] if "x" in vd else 0.0), -// // y=float(vd["y"] if "y" in vd else 0.0), -// // value=vd["value"] if "value" in vd else "", -// // name=int(v)) -// // for e, ed in j["edges"].items(): -// // g.add_edge(s=[int(v) for v in ed["s"]], -// // t=[int(v) for v in ed["t"]], -// // value=ed["value"] if "value" in ed else "", -// // x=float(ed["x"]) if "x" in ed else 0.0, -// // y=float(ed["y"]) if "y" in ed else 0.0, -// // hyper=bool(ed["hyper"]) if "hyper" in ed else True, -// // name=int(e)) -// // -// // g.set_inputs([int(v) for v in j["inputs"]]) -// // g.set_outputs([int(v) for v in j["outputs"]]) -// // json.vertices.forEach(((vertex, i) => graph.add_vertex( -// // i, -// // new VData() -// // )); -// -// return graph; -// } -// -// /** -// * # def wide_id() -> Graph: -// * # return gen("id", 1, 1) -// * -// * # def id_perm(p: List[int]) -> Graph: -// * # g = Graph() -// * # size = len(p) -// * # inputs = [g.add_vertex(-1.5, i - (size-1)/2) for i in range(size)] -// * # outputs = [g.add_vertex(1.5, i - (size-1)/2) for i in range(size)] -// * -// * # for i in range(size): -// * # y = i - (size-1)/2 -// * # g.add_edge([inputs[i]], [outputs[p[i]]], "id", 0, y) -// * -// * # g.set_inputs(inputs) -// * # g.set_outputs(outputs) -// * -// * # return g -// */ -// -// /** -// * Return a graph corresponding to a vertex size redistribution. -// * -// * A specific case of this family of graphs are 'dividers', which split a vertex of some type and size into multiple size 1 vertices of the same type. Conversely, 'gatherers' bundle multiple vertices of the same type into a single vertex of the same type and size the sum of the individual input vertex sizes. -// * -// * More generally, a conversion can be done between different lists of sizes, for some vertex type. -// * -// * @param domain A list of pairs (vertex type, register size) corresponding to each input vertex. -// * @param codomain A list of pairs (vertex type, register size) corresponding to each output vertex. -// */ -// redistributer = (domain = list, codomain = list) => { -// /** -// * vtypes = set(vtype for vtype, _ in domain) -// * vtypes.update(vtype for vtype, _ in codomain) -// * if len(vtypes) > 1: -// * raise GraphError('Size conversion cannot mix vertex types.') -// * -// * # Raise error if size conservation is violated -// * domain_size = sum(size for _, size in domain) -// * codomain_size = sum(size for _, size in codomain) -// * if domain_size != codomain_size: -// * raise GraphError(f'Sum of domain sizes ({domain_size}) does not equal' -// * + f'sum of codomain sizes ({codomain_size}).') -// * -// * return gen('_redistributer', domain, codomain) -// */ -// -// } -// -// /** -// * Some more delegations here -// */ -// match_graph = (domain: Graph, codomain: Graph, convex: boolean = true): Matches => domain.match(codomain, convex); -// match_rule = (rule: Rule, codomain: Graph, convex: boolean = true): Matches => rule.match(codomain, convex); -// find_iso = (domain: Graph, codomain: Graph): Match => domain.find_iso(codomain); -// } -// -// export class CodeView extends Ray { -// __init__ = (): Ray.Any => { throw new NotImplementedError(); } -// popup_visible = (): Ray.Any => { throw new NotImplementedError(); } -// set_completions = (completions = Iterable(str)): Ray.Any => { throw new NotImplementedError(); } -// ident_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } -// insert_completion = (completion = str): Ray.Any => { throw new NotImplementedError(); } -// keyPressEvent = (e = QKeyEvent): Ray.Any => { throw new NotImplementedError(); } -// set_current_region = (region = Optional(Tuple(int,int))): Ray.Any => { throw new NotImplementedError(); } -// add_line_below = (text = str): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class CodeCompletionModel extends Ray { -// __init__ = (parent = QObject): Ray.Any => { throw new NotImplementedError(); } -// set_completions = (completions = Iterable(str)): Ray.Any => { throw new NotImplementedError(); } -// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray.Any => { throw new NotImplementedError(); } -// rowCount = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class ChypDocument extends Ray { -// __init__ = (parent = QWidget): Ray.Any => { throw new NotImplementedError(); } -// confirm_close = (): Ray.Any => { throw new NotImplementedError(); } -// add_to_recent_files = (file_name = str): Ray.Any => { throw new NotImplementedError(); } -// open = (file_name = str): Ray.Any => { throw new NotImplementedError(); } -// save = (): Ray.Any => { throw new NotImplementedError(); } -// save_as = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class Editor extends Ray { -// __init__ = (): Ray.Any => { throw new NotImplementedError(); } -// title = (): Ray.Any => { throw new NotImplementedError(); } -// reset_state = (): Ray.Any => { throw new NotImplementedError(); } -// invalidate_text = (): Ray.Any => { throw new NotImplementedError(); } -// next_part = (): Ray.Any => { throw new NotImplementedError(); } -// jump_to_error = (): Ray.Any => { throw new NotImplementedError(); } -// show_errors = (): Ray.Any => { throw new NotImplementedError(); } -// show_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } -// next_rewrite_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } -// repeat_step_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } -// update_state = (): Ray.Any => { throw new NotImplementedError(); } -// import_at_cursor = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class CheckThread extends Ray { -// __init__ = (rw = RewriteState): Ray.Any => { throw new NotImplementedError(); } -// run = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class ErrorListModel extends Ray { -// __init__ = (): Ray.Any => { throw new NotImplementedError(); } -// set_errors = (errors = List(Tuple(str, int, str))): Ray.Any => { throw new NotImplementedError(); } -// data = (index = Union(QModelIndex, QPersistentModelIndex)): Ray.Any => { throw new NotImplementedError(); } -// headerData = (section = int, orientation = Orientation): Ray.Any => { throw new NotImplementedError(); } -// index = (row = int, column = int): Ray.Any => { throw new NotImplementedError(); } -// columnCount = (): Ray.Any => { throw new NotImplementedError(); } -// rowCount = (): Ray.Any => { throw new NotImplementedError(); } -// parent = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class EItem extends Ray { -// __init__ = (g = Graph, e = int): Ray.Any => { throw new NotImplementedError(); } -// paint = (painter = QPainter, option = QStyleOptionGraphicsItem): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class VItem extends Ray { -// __init__ = (g = Graph, v = int): Ray.Any => { throw new NotImplementedError(); } -// refresh = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class TItem extends Ray { -// __init__ = (vitem = VItem, eitem = EItem, i = int, src = bool): Ray.Any => { throw new NotImplementedError(); } -// refresh = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class GraphScene extends Ray { -// __init__ = (): Ray.Any => { throw new NotImplementedError(); } -// set_graph = (g = Graph): Ray.Any => { throw new NotImplementedError(); } -// add_items = (): Ray.Any => { throw new NotImplementedError(); } -// mousePressEvent = (e = QGraphicsSceneMouseEvent): Ray.Any => { throw new NotImplementedError(); } -// mouseMoveEvent = (e = QGraphicsSceneMouseEvent): Ray.Any => { throw new NotImplementedError(); } -// mouseReleaseEvent = (_ = QGraphicsSceneMouseEvent): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class GraphView extends Ray { -// __init__ = (): Ray.Any => { throw new NotImplementedError(); } -// set_graph = (g = Graph): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class ChypHighlighter extends Ray { -// __init__ = (doc = QTextDocument): Ray.Any => { throw new NotImplementedError(); } -// set_current_region = (region = Optional(Tuple(int,int)), status = int): Ray.Any => { throw new NotImplementedError(); } -// highlightBlock = (text = str): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class MainWindow extends Ray { -// __init__ = (): Ray.Any => { throw new NotImplementedError(); } -// remove_empty_editor = (): Ray.Any => { throw new NotImplementedError(); } -// update_file_name = (): Ray.Any => { throw new NotImplementedError(); } -// tab_changed = (i = int): Ray.Any => { throw new NotImplementedError(); } -// update_themes = (): Ray.Any => { throw new NotImplementedError(); } -// recent_files = (): Ray.Any => { throw new NotImplementedError(); } -// update_recent_files = (): Ray.Any => { throw new NotImplementedError(); } -// add_tab = (ed = Editor, title = str): Ray.Any => { throw new NotImplementedError(); } -// close_tab = (): Ray.Any => { throw new NotImplementedError(); } -// new = (): Ray.Any => { throw new NotImplementedError(); } -// open = (): Ray.Any => { throw new NotImplementedError(); } -// save = (): Ray.Any => { throw new NotImplementedError(); } -// save_as = (): Ray.Any => { throw new NotImplementedError(); } -// undo = (): Ray.Any => { throw new NotImplementedError(); } -// redo = (): Ray.Any => { throw new NotImplementedError(); } -// show_errors = (): Ray.Any => { throw new NotImplementedError(); } -// add_rewrite_step = (): Ray.Any => { throw new NotImplementedError(); } -// repeat_rewrite_step = (): Ray.Any => { throw new NotImplementedError(); } -// next_rewrite = (): Ray.Any => { throw new NotImplementedError(); } -// next_part = (): Ray.Any => { throw new NotImplementedError(); } -// previous_part = (): Ray.Any => { throw new NotImplementedError(); } -// next_tab = (): Ray.Any => { throw new NotImplementedError(); } -// previous_tab = (): Ray.Any => { throw new NotImplementedError(); } -// goto_import = (): Ray.Any => { throw new NotImplementedError(); } -// closeEvent = (e = QCloseEvent): Ray.Any => { throw new NotImplementedError(); } -// build_menu = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// // TODO ISNT A MATCH JUST AN IGNORANT COPY ON BOTH SIDES??? -// export class Match extends Ray { -// -// get vertex_map(): Ray.Any { throw new NotImplementedError(); } -// get vertex_image(): Ray.Any { throw new NotImplementedError(); } -// get edge_map(): Ray.Any { throw new NotImplementedError(); } -// get edge_image(): Ray.Any { throw new NotImplementedError(); } -// -// __str__ = (): Ray.Any => { -// // (f'\tVertex map: {str(self.vertex_map)}' -// // + f'\n\tEdge map: {str(self.edge_map)}') -// // TODO -// throw new NotImplementedError(); } -// -// // Implemented on Ray -// // TODO; doesnt copy the graphs at domain/codomain -// // copy = (): Ray.Any => { throw new NotImplementedError(); } -// -// /** -// * Try to map `domain_vertex` to `codomain_vertex`. -// * -// * This map must satisfy various conditions, such as only being allowed to be non-injective on the boundary domain vertices. -// * -// * Returns: `True` if either a consistent map from `domain_vertex` to already exists or the new map is consistent and satisfies the gluing conditions, otherwise `False`. -// */ -// try_add_vertex = (domain_vertex: VData, codomain_vertex: VData): Ray.Any => { -// -// // If the vertex is already mapped, only check the new mapping is consistent with the current match. -// if (this.vertex_map.includes(domain_vertex)) { -// log(`Vertex already mapped to ${this.vertex_map[domain_vertex]}.`) -// return this.vertex_map[domain_vertex] === codomain_vertex; -// } -// -// // TODO: ALL THESE SHOULD JUST BE AN EQUIVALENCY CHECK, JUST LIKE MATCHING/// - You can't actually guarantee consistency, it's just a simple ignorant check. - We can probably just remove this as soon as the equivalency check is implemented. -// // TODO: This should all be redundant, probably removed ... -// -// // Ensure the mapping preserves vertex type. -// if (domain_vertex.vtype !== codomain_vertex.vtype) { -// log(`Vertex failed: vtypes ${domain_vertex.vtype} != ${codomain_vertex.vtype} do not match.`); -// -// return bool(False); -// } -// -// // Ensure the mapping preserves vertex size. -// if (domain_vertex.size !== codomain_vertex.size) { -// log(`Vertex failed: sizes ${domain_vertex.size} != ${codomain_vertex.size} do not match.`) -// return bool(False); -// } -// -// // Ensure non-boundary vertices in the domain are not mapped to boundary vertices in the codomain. -// if (!codomain_vertex.is_boundary() && !domain_vertex.is_boundary()) { -// log('Vertex failed: codomain vertex is boundary but domain vertex is not.') -// return bool(False); -// } -// -// // Matches must be injective everywhere except the boundary, so if the domain vertex is already mapped to another codomain vertex, check whether this non-injective mapping is permitted. -// if (this.vertex_image.includes(codomain_vertex)) { -// // If the domain vertex we are trying to add is not a boundary vertex, it cannot be used in a non-injective mapping. -// if (!domain_vertex.is_boundary()) { -// log('Vertex failed: non-injective on interior vertex.') -// return bool(False); -// } -// -// // If any vertices already mapped to the codomain vertex, they must also be boundary vertices for an allowed non-injective mapping. -// if (this.vertex_image.any(([mapped_vertex, image_vertex]) => -// image_vertex === codomain_vertex && !mapped_vertex.is_boundary() // TODO mapped_vertex on domain!! -// )) { -// log('Vertex failed: non-injective on interior vertex.') -// return bool(False); -// } -// -// return bool(False); -// } -// -// // If a new and consistent map is found, add it to the vertex map of this match. -// this.vertex_map[domain_vertex] = codomain_vertex -// this.vertex_image.add(codomain_vertex) -// -// // Unless the domain vertex is a boundary vertex, check that the number of adjacent edges of the codomain vertex is the same as the number for the domain vertex. Because matchings are required to be injective on edges, this will guarantee that the gluing conditions are satisfied. -// -// if (!domain_vertex.is_boundary()) { -// if (domain_vertex.in_edges.count.as_int() !== codomain_vertex.in_edges.count.as_int()) { -// log('Vertex failed: in_edges cannot satisfy gluing conditions.') -// return bool(False) -// } -// if (domain_vertex.out_edges.count.as_int() !== codomain_vertex.out_edges.count.as_int()) { -// log('Vertex failed: in_edges cannot satisfy gluing conditions.') -// return bool(False) -// } -// } -// -// // If a new consistent map is added that satisfies the gluing conditions, we are successful. -// log('Vertex success.') -// return bool(True); -// } -// -// /** -// * Try to map `domain_edge` to `codomain_edge`. -// * -// * This must satisfy certain conditions, such as being injective and having consistency with the vertex map. -// * -// * @param domain_edge -// * @param codomain_edge -// * -// * `True` if a consistent match is found mapping `domain_edge` to `codomain_edge`, otherwise `False`. -// */ -// try_add_edge = (initial: EData, terminal: EData): Ray.Any => { -// log(`Trying to add edge ${initial} -> ${terminal} to match:`); -// log(this.toString()); -// -// // TODO: Again an equivalence -// // Check the values of the domain and codomain edges match. -// if (initial.value !== terminal.value) { -// log(`Edge failed: values ${initial.value} != ${terminal.value}`) -// return false; -// } -// -// // The edge map must be injective. -// if (this.edge_image.includes(terminal)) { -// console.log('Edge failed: the map would become non-injective.'); -// return false; -// } -// -// // If the values match and the codomain edge has not already been mapped to, map domain edge to codomain edge. -// this.edge_map[initial] = terminal; -// this.edge_image.add(terminal); -// -// // Domain sources must match codomain sources and domain targets must match codomain targets. -// -// // TODO: Again more equivalences, just to log - debug mode -// { -// // initial = preimg -// // terminal = image -// -// // Domain sources must match codomain sources and domain targets must match codomain targets. -// if (initial.domain !== terminal.domain) { -// log(`Edge domain ${initial.domain} does not match image domain ${terminal.domain}.`); -// } -// -// // TODO, again both sides -// if (initial.codomain !== terminal.codomain) { -// log(`Edge codomain ${initial.codomain} does not match image codomain ${terminal.codomain}.`); -// } -// } -// -// // TODO: This too probably general pattern to extract -// // Check a vertex map consistent with this edge pairing exists. -// // TODO: + here is just concat, so that zip can easily match it -// ([initial.source + initial.target, terminal.source + terminal.target] as Ray).zip(([initial_vertex, terminal_vertex]) => { -// // Each vertex that is already mapped needs to be consistent. -// // TODO: More equivlaency, could be on the vertecies themselves -// if (this.vertex_map.includes(initial_vertex) && this.vertex_image[initial_vertex] !== terminal_vertex) { -// log('Edge failed: inconsistent with previously mapped vertex.'); -// return false; // TODO: NOT RETURNING AGAIN -// } -// -// // Otherwise, a consistent match must be found vertex for unmapped source and target vertices. -// -// if (!this.try_add_vertex(initial_vertex, terminal_vertex)) { -// log('Edge failed: couldn\'t add a source or target vertex.'); -// return false; -// } -// }); -// -// log('Edge success.'); -// return true; -// } -// -// /** -// * Return whether all adjacent edges of a domain vertex are mapped. -// */ -// domain_neighbourhood_mapped = (vertex: VData): Ray.Any => -// ([vertex.in_edges + vertex.out_edges] as Ray).all(edge => this.edge_map.includes(edge)); -// -// /** -// * # def cod_nhd_mapped(self, cod_v: int): -// * # """Returns True if nhd(cod_v) is the range of emap""" -// * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and -// * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) -// */ -// -// /** -// * Try to extend the match by mapping all scalars (i.e. 0 -> 0 edges). -// * -// * Note that any matchings of scalars will yield isomorphic results under rewriting, so we don't return a list of all the possible matchings. -// * -// * Returns: `True` if all scalars in the domain are mapped injectively to scalars in the codomain, otherwise `False`. -// */ -// map_scalars = (): Ray.Any => { -// //TODO WHAT'S A SCALAR HERE? -// // TODO: Again same pattern for (co)domain - flipped, two dimensional -// const ___scalars = (domain: Graph, reverse: boolean) => { -// const is = (ray: Ray.Any) => reverse ? ray.count !== 0 : Ray.Any.count === 0; // TODO: Should be easier to just .not this -// -// return domain.edges -// .filter((edge: EData) => this.is(edge.source) && this.is(edge.target)); -// } -// -// const terminal = ___scalars(this.codomain, false); -// const initial = ___scalars(this.domain, true); -// -// // Greedily try to map scalar edges in the domain to scalar edges in the codomain with the same value. -// initial.all((initial_edge: EData) => { -// // TODO: Put initial/terminal edge on a ray and then apply funcitons -// -// log(`Trying to map scalar edge ${initial_edge}`) -// -// let found_match = false; -// -// // TODO .enumerate?? -// terminal.all(([i, terminal_edge]) => { -// if (initial_edge.value !== terminal_edge.value) // ANother equiv -// return; // TODO continue; -// -// // Map the domain scalar to the first codomain scalar available with the same value. -// this.edge_map[initial_edge] = terminal_edge; -// this.edge_image.add(terminal_edge); // TODO: Again map/image is just initial/terminal.. same as domain/codomain,, -// -// found_match = true; -// -// // Since the edge map must be injective, if a scalar in the codomain is mapped to, remove it from the list of candidates for future domain scalars to be mapped to. -// terminal.pop(i); // TODO: ??? -// -// log(`Successfully mapped scalar ${initial_edge} -> ${terminal_edge}`) -// -// // TODO: BREAK ; any?? -// }); -// -// if (!found_match) { -// log(`Match failed: could not map scalar edge ${initial_edge}.`) -// return false; // TODO DOESNT RETURN -// } -// }); -// -// return true; -// } -// -// -// // TODO: IF MORE JUST ADDS MORE MATCHES IN THIS DIRECTION, THAT SHOULD BE AUTOMATIC ON .match ... ? -// /** -// * Return any matches extending `self` by a single vertex or edge. -// */ -// more = (): Ray.Any => { -// // First, try to add an edge adjacent to any domain vertices that have already been matched. -// this.vertex_map -// // If all the edges adjacent to the current vertex have already been matched, continue. TODO: Could just be on the .vertex -// .filter(initial_vertex => this.domain_neighbourhood_mapped(initial_vertex)) -// .all((initial_vertex: VData) => { -// // TODO: AS ZIp or something -// const terminal_vertex = this.vertex_map[initial_vertex]; -// -// const ___test = (boundary: (ray: Graph) => Ray.Any): Ray.Any => { -// // Try to extend the match by mapping an adjacent source edge. -// boundary(this.domain) // TODO: AGAIN SAME THING -// // If the edge has already been matched, continue. -// .filter(edge => !this.edge_map.includes(edge)) -// .all((initial_edge: EData) => { -// -// // Otherwise, try to map this edge into the codomain graph. -// return boundary(this.codomain).map(terminal_edge => { -// const potential_new_match = this.copy(); -// -// // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. -// if (potential_new_match.try_add_edge(initial_edge, terminal_edge)) -// return potential_new_match; -// -// return NONE;//todo -// }); // TODO REMOVE NON-ADDED_ONES, doesnt actually reutn either -// }) -// -// } -// -// ___test(ray => Ray.Any.in_edges); -// ___test(ray => Ray.Any.out_edges); -// -// }); -// -// // If all domain edges adjacent to matched domain vertices have already been matched, try to match an unmatched domain vertex. -// this.domain.vertices -// // If the vertex has already been matched into the codomain graph, continue. (Note we have looked at the edge-neighbourhood of these vertices above) -// .filter(initial_vertex => this.vertex_map.includes(initial_vertex)) // TODO: THIS THING IS JUST A COPY, AGAIN FROM THE VERTEX/EDGE DIFFERENTIATION FROM ABOVE -// .all(initial_vertex => { -// -// // Try to map the current domain vertex to any of the codomain vertices, extending the current match with this map when successful. -// return this.codomain.vertices.map((terminal_vertex: VData) => { -// const potential_new_match = this.copy(); -// -// // If the edge is successfully mapped to an edge in the codomain graph, extend the match with this mapping. -// if (potential_new_match.try_add_vertex(initial_edge, terminal_edge)) -// return potential_new_match; -// -// return NONE;//todo -// }); // TODO: AGAIN DOESNT RETURN -// }) -// -// return []; -// } -// -// // TODO: Total=surjective on another level of description ??? -// ___defuq = (string: 'image' | 'map', domain) => -// this[`vertex_${string}`].count === domain.vertices.count -// && this[`edge_${string}`].count === domain.edges.count; // TODO: Again vertex/edge pattern, just collapse to one check -// -// /** -// * Return whether all domain vertices and edges have been mapped. -// */ -// is_total = (): Ray.Any => this.___defuq('map', this.domain); -// /** -// * Return whether the vertex and edge maps are surjective. -// */ -// is_surjective = (): Ray.Any => this.___defuq('image', this.codomain); -// -// /** -// * Return whether the vertex and edge maps are injective. -// */ -// is_injective = (): Ray.Any => { -// // Since the edge map is always injective, we only need to check the vertex map is injective. TODO (GENERALIZE) -// return this.vertex_map.count === this.vertex_image.count; -// } -// -// /** -// * Return whether this match is convex. -// * -// * A match is convex if: -// * - It is injective. -// * - Its image in the codomain hypergraph is a convex sub-hypergraph. This means that for any two nodes in the sub-hypergraph and any path between these two nodes, every hyperedge along the path is also in the sub-hypergraph. -// * -// * TODO: Just no overlap?? -// */ -// is_convex = (): Ray.Any => { -// if (!this.is_injective()) { //TODO: WHY? -// return false; -// } -// -// -// // Check that the image sub-hypergraph is convex. Get all successors of vertices in the image of the output of the domain graph. -// const output_image_successors = this.codomain.successors( -// this.domain.outputs -// .filter(vertex => this.vertex_map[vertex]) // TODO INCLUDES -// ); // TODO, Why search in codomain fromi these, ?? this must be easier -// -// // Check there is no path from any vertices in the image of the domain outputs to a vertex in the image of the domain inputs. -// this.domain.inputs -// .filter(vertex => this.vertex_map.includes(vertex) && output_image_successors.includes(this.vertex_map[vertex])) -// .any(() => { return false }) // TODO DOESNT ACTUALLY RETURNM -// -// return true; -// } -// -// /** -// * TODO Not implemented;; -// * # def cod_nhd_mapped(self, cod_v: int): -// * # """Returns True if nhd(cod_v) is the range of emap""" -// * # return (all(e in self.eimg for e in self.cod.in_edges(cod_v)) and -// * # all(e in self.eimg for e in self.cod.out_edges(cod_v))) -// */ -// } -// -// /** -// * An iterator over matches of one graph into another. -// * -// * This class can be used to iterate over total matches of a graph into another, optionally requiring these matches to be convex. -// * -// * TODO: SUPPORT THIS/?::: -// * A class instance works by keeping a stack of partial or total matches. -// * When it is iterated over, it pops a match from its match stack if it is -// * non-empty, otherwise the iteration is stopped. If a match has been popped, -// * the instance returns the match if it is total (and convex if required). -// * Otherwise, the instance tries to extend the match and add any extended -// * matches to the stack, then continues this process of popping off the match -// * stack and extending if possible until a valid match is found and returned. -// */ -// export class Matches extends Ray { -// __init__ = (domain = Graph, codomain = Graph): Ray.Any => { -// /** -// * TODO -// * if initial_match is None: -// * initial_match = Match(domain=domain, codomain=codomain) -// * self.convex = convex -// * -// * # Try to map scalars on the initial match. -// * if initial_match.map_scalars(): -// * self.match_stack = [initial_match] -// * # If the scalars could not be mapped, set the match -// * # stack to be empty. This means that not suitable matches -// * # will be found by this class instance. -// * else: -// * self.match_stack = [] -// */ -// throw new NotImplementedError(); } -// __iter__ = (): Ray.Any => { throw new NotImplementedError(); } -// -// /** -// * Return the next suitable match found. -// * -// * A 'suitable' match is one that is total and, if `self.convex == True`, convex. -// */ -// __next__ = (): Ray.Any => { -// // TODO Like expected this, class can probably be dropped this just becomes -// -// return this.match_stack.dont_check_for_convex_or.is_convex; // TODO: Just generalize these on functions -// -// /** -// * while len(self.match_stack) > 0: -// * # Pop the match at the top of the match stack -// * m = self.match_stack.pop() -// * # If the match is total (and convex if required), return it. -// * if m.is_total(): -// * match_log("got successful match:\n" + str(m)) -// * if self.convex: -// * if m.is_convex(): -// * match_log("match is convex, returning") -// * return m -// * else: -// * match_log("match is not convex, dropping") -// * else: -// * return m -// * # If the match at the top of the match stack was not total -// * # (and convex if required), try to extend the match at the -// * # top of the stack and add the results to the match stack. -// * else: -// * self.match_stack += m.more() -// * # If a suitable match was not found, stop the iteration. -// * raise StopIteration -// */ -// } -// } -// -// export class Rule extends Ray { -// -// get equiv(): Ray.Any { throw new NotImplementedError(); } -// -// -// /** -// * Returns True if boundary on lhs embeds injectively -// */ -// is_left_linear = (): Ray.Any => { -// // TODO, needs to implement splat and stuff? or by default, could be done smarter, but again no overloading - Or should just equivalence a copy?? -// return !JS.Iterable([...this.lhs.inputs, ...this.rhs.outputs]).as_ray() -// .has_duplicates() // TODO; This thing is basically asking whether any input is used twice, whether any output is used twice, or there's a circle between in/output? Basically: NO SELF-REFERENCE, this should be a very sikmple check whether any frame is used twice here - or some loop is found basically. -// } -// -// /** -// * Do double-pushout rewriting -// * -// * Given a rule r and match of r.lhs into a graph, return a match of r.rhs into the rewritten graph. -// * @param match -// */ -// dpo = (match: Match): Ray.Any => { -// // if (!this.is_left_linear()) -// // throw new NotImplementedError("Only left linear rules are supported for now") -// -// const rewritten_graph: Graph = match.codomain.copy(); -// -// // TODO: This will definitely be rewritten, this is an ugly implementation. Just draw the lines and be ignorant in that direction ??? Probably just implement it as additional filtering on .copy()??? -// -// // Computes the push complement ?? (just the thing we're replacing right?) -// // TODO: Removes the match from the copy? -// this.lhs.edges.all(edge => rewritten_graph.remove_edge(match.edge_map(edge))); -// -// const inputs = []; -// const outputs = []; -// -// this.lhs.vertices.all(rule_vertex => { -// const match_vertex = match.vertex_map[rule_vertex]; -// -// if (!this.lhs.is_boundary(rule_vertex)) { -// rewritten_graph.remove_vertex(match_vertex); -// return; -// } -// -// const rule_input = rule_vertex.in_indices; -// const rule_output = rule_vertex.out_indices; -// -// if (rule_input.count.as_int() === 1 && rule_output === 1) { -// const [match_input, match_output] = rewritten_graph.explode_vertex(match_vertex); -// -// if (match_input.count.as_int() !== 1 && match_output.count.as_int() !== 1) -// throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); -// -// inputs[rule_vertex] = match_input[0]; -// outputs[rule_vertex] = match_output[0]; -// } else if (rule_input.count.as_int() > 1 || rule_output.count.as_int() > 1) { -// throw new NotImplementedError("Rewriting modulo Frobenius not yet supported."); -// } -// }) -// -// // Embed Rule.rhs into rewritten_graph -// const replacement = new Match(this.rhs, rewritten_graph); -// -// // TODO: This is probably another of these geeneral patterns, same thing on either ends composed as a single ray., -// const input = new Ray(); // [this.lhs.inputs, this.rhs.inputs] -// -// // first map the inputs, using the matching of the lhs -// input.zip().all(([initial, terminal]) => { -// match.vertex_map[terminal] = inputs.includes(initial) ? inputs[initial] : match.vertex_map[initial]; -// }); -// -// const output = new Ray(); // [this.lhs.outputs, this.rhs.outputs] -// -// // next map the outputs. if the same vertex is an input and an output in r.rhs, then merge them in h. -// output.zip().all(([initial, terminal]) => { -// // TODO: Again, both ends are very similar, there should probably be a direct flip in these, small difference at the end -// const temp = outputs.includes(initial) ? outputs[initial] : match.vertex_map[initial]; -// -// if (match.vertex_map.includes(terminal)) { -// rewritten_graph.merge_vertices(match.vertex_map[terminal], temp) -// } else { -// match.vertex_map[terminal] = temp; -// } -// }); -// -// // then map the interior to new, fresh vertices -// this.rhs.vertices -// .filter(vertex => !vertex.is_boundary()) -// .all((vertex: VData) => { -// // TODO Again the fresh thing repeated here - just because it's moving between graphs -// const new_vertex = rewritten_graph.add_vertex(vertex.fresh()); -// -// match.vertex_map[vertex] = new_vertex; -// match.vertex_image.add(new_vertex); -// }); -// -// // now add the edges from rhs to h and connect them using vmap1 -// // TODO: Again this should be the same thing as the vertices -// this.rhs.edges. -// all((edge: EData) => { -// const new_edge = rewritten_graph.add_edge(); -// /** -// * e1 = h.add_edge([m1.vertex_map[v] for v in ed.s], -// * [m1.vertex_map[v] for v in ed.t], -// * ed.value, ed.x, ed.y, ed.fg, ed.bg, ed.hyper) -// */ -// -// match.edge_map[edge] = new_edge; -// match.edge_image.add(new_edge); -// }) -// -// return replacement; -// } -// -// // TODO: Can probably just match Rule=Graph, and use only one of these methods?? -// /** -// * Return matches of the left side of `rule` into `graph`. -// */ -// match = (other: Graph, convex: boolean = true): Matches => new Matches(this.lhs, other, convex); -// -// /** -// * Apply the given rewrite r to at match m and return the first result -// * -// * This is a convenience wrapper for `dpo` for when the extra rewrite data isn't needed. -// */ -// rewrite = (match: Match): Ray.Any => this.dpo(match).first.terminal; // .first.codomain -// // TODO; Though .first is used here, something like .any is more appropriate in the sense of: Don't care which one first, just something. -// } -// -// export class RewriteState extends Ray { -// __init__ = (sequence = int, state = State): Ray.Any => { throw new NotImplementedError(); } -// check = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class State extends Ray { -// __init__ = (): Ray.Any => { throw new NotImplementedError(); } -// part_with_index_at = (pos = int): Ray.Any => { throw new NotImplementedError(); } -// part_at = (pos = int): Ray.Any => { throw new NotImplementedError(); } -// var = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// module_name = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// num = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// type_element = (items = list(Any)): Ray.Any => { throw new NotImplementedError(); } -// type_term = (items = list(JS.Iterable([tuple(JS.Iterable([str, None]), int), None]))): Ray.Any => { throw new NotImplementedError(); } -// id = (items = list(Any)): Ray.Any => { throw new NotImplementedError(); } -// id0 = (_ = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// eq = (_ = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// le = (_ = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// perm_indices = (items = list(int)): Ray.Any => { throw new NotImplementedError(); } -// size_list = (items = list(int)): Ray.Any => { throw new NotImplementedError(); } -// par = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// gen_color = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// color = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// import_let = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// tactic = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// nested_term = (items = List(Any)): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class Tactic extends Ray { -// __init__ = (local_state = RewriteState, args = List(str)): Ray.Any => { throw new NotImplementedError(); } -// repeat = (rw = Callable([str], bool), rules = List(str)): Ray.Any => { throw new NotImplementedError(); } -// error = (message = str): Ray.Any => { throw new NotImplementedError(); } -// has_goal = (): Ray.Any => { throw new NotImplementedError(); } -// global_rules = (): Ray.Any => { throw new NotImplementedError(); } -// lookup_rule = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } -// add_refl_to_context = (graph = Graph, ident = str): Ray.Any => { throw new NotImplementedError(); } -// add_rule_to_context = (rule_name = str): Ray.Any => { throw new NotImplementedError(); } -// __lhs = (target = str): Ray.Any => { throw new NotImplementedError(); } -// __rhs = (target = str): Ray.Any => { throw new NotImplementedError(); } -// __set_lhs = (target = str, graph = Graph): Ray.Any => { throw new NotImplementedError(); } -// __set_rhs = (target = str, graph = Graph): Ray.Any => { throw new NotImplementedError(); } -// rewrite_lhs = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } -// rewrite_rhs = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } -// rewrite_lhs1 = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } -// rewrite_rhs1 = (rule_expr = str): Ray.Any => { throw new NotImplementedError(); } -// validate_goal = (): Ray.Any => { throw new NotImplementedError(); } -// lhs = (): Ray.Any => { throw new NotImplementedError(); } -// rhs = (): Ray.Any => { throw new NotImplementedError(); } -// lhs_size = (): Ray.Any => { throw new NotImplementedError(); } -// rhs_size = (): Ray.Any => { throw new NotImplementedError(); } -// highlight_lhs = (vertices = Set(int), edges = Set(int)): Ray.Any => { throw new NotImplementedError(); } -// highlight_rhs = (vertices = Set(int), edges = Set(int)): Ray.Any => { throw new NotImplementedError(); } -// __reset = (): Ray.Any => { throw new NotImplementedError(); } -// next_rhs = (current = str): Ray.Any => { throw new NotImplementedError(); } -// run_check = (): Ray.Any => { throw new NotImplementedError(); } -// name = (): Ray.Any => { throw new NotImplementedError(); } -// check = (): Ray.Any => { throw new NotImplementedError(); } -// make_rhs = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class RuleTac extends Ray { -// name = (): Ray.Any => { throw new NotImplementedError(); } -// make_rhs = (): Ray.Any => { throw new NotImplementedError(); } -// check = (): Ray.Any => { throw new NotImplementedError(); } -// } -// -// export class SimpTac extends Ray { -// name = (): Ray.Any => { throw new NotImplementedError(); } -// __prepare_rules = (): Ray.Any => { throw new NotImplementedError(); } -// make_rhs = (): Ray.Any => { throw new NotImplementedError(); } -// check = (): Ray.Any => { throw new NotImplementedError(); } -// } -// diff --git a/orbitmines.com/src/@orbitmines/external/chyp/README.md b/orbitmines.com/src/@orbitmines/external/chyp/README.md deleted file mode 100644 index 15b77d3..0000000 --- a/orbitmines.com/src/@orbitmines/external/chyp/README.md +++ /dev/null @@ -1,9 +0,0 @@ -An interface from Aleks Kissinger's [Chyp (Cospans of HYPergraphs)](https://github.com/akissinger/chyp) to (OrbitMines') Ray. - -**What is this?, What are Rays?** - -See the `README.md` at [github.com/orbitmines/orbitmines.com](https://github.com/orbitmines/orbitmines.com). Or locally: [README.md](../../../../README.md) - -**Why is this interface here?** - -Note that this is mainly here for reference to the existing Chyp codebase - for anyone who understands that structure, to quickly translate that knowledge into how Rays work. - Other than that functionality, everything here should be considered as deprecated. Or considered as a legacy translation, which will be accessibly through OrbitMines. \ No newline at end of file diff --git a/orbitmines.com/src/@orbitmines/external/chyp/examples.ts b/orbitmines.com/src/@orbitmines/external/chyp/examples.ts deleted file mode 100644 index 581b15c..0000000 --- a/orbitmines.com/src/@orbitmines/external/chyp/examples.ts +++ /dev/null @@ -1,76 +0,0 @@ -{/* Iterator */} -{/**/} -{/* */} -{/* */} -{/**/} - -{/* Grid/Dictionary/... */} -{/**/} -{/* */} -{/* */} -{/* */} -{/* */} -{/* */} -{/**/} - -{/* Loop memory */} -{/**/} -{/* */} -{/* */} -{/**/} - - - -{/* Being able to reference any part from within the structure - self-compiling */} -{/**/} -{/* */} -{/* */} -{/* /!**!/*/} -{/**/} - -{/* Continuation expanded */} -{/**/} -{/* */} - -{/* */} -{/* */} -{/* */} -{/* /!**!/*/} -{/**/} - - -{/**/} -{/* */} -{/* */} -{/* */} -{/* */} - -{/* */} -{/* */} -{/* */} -{/* */} - -{/* */} -{/* */} - -{/* */} - -{/**/} - -{/**/} -{/* */} -{/* */} -{/* */} - -{/* */} -{/* */} -{/* */} -{/**/} diff --git a/orbitmines.com/src/App.tsx b/orbitmines.com/src/App.tsx index c63fdcb..f8a1f3a 100755 --- a/orbitmines.com/src/App.tsx +++ b/orbitmines.com/src/App.tsx @@ -7,15 +7,11 @@ import Root from "./routes/Root"; import Paper from "./routes/Paper"; import Profile from "./routes/Profiles"; import {Helmet} from "react-helmet"; -import OrbitMinesExplorer from "./@orbitmines/explorer/OrbitMinesExplorer"; import Legacy from "./lib/layout/experimental-designs/Legacy"; import BlueprintJS from "./lib/layout/experimental-designs/BlueprintJS"; import Modules from "./@orbitmines/js/react/Modules"; import Icons from "./lib/layout/experimental-designs/Icons"; import {ThumbnailPage} from "./lib/paper/Paper"; -import {ChypExplorer} from "./@orbitmines/external/chyp/ChypCanvas"; -import {DebugExplorer} from "./@orbitmines/explorer/debug/DebugCanvas"; -import {QuickVisualizationExplorer} from "./@orbitmines/explorer/debug/QuickVisualizationInterface"; export const Router = () => { @@ -28,17 +24,18 @@ export const Router = () => { } /> } /> - - } /> - } /> + {/* TODO */} + {/**/} + {/*} />*/} + {/*} />*/} {/*} />*/} - - - } /> - - - + {/**/} + {/* */} + {/* } />*/} + {/* */} + {/**/} + {/**/} } /> } /> diff --git a/orbitmines.com/src/lib/paper/Paper.tsx b/orbitmines.com/src/lib/paper/Paper.tsx index 66b5cdf..9a06285 100644 --- a/orbitmines.com/src/lib/paper/Paper.tsx +++ b/orbitmines.com/src/lib/paper/Paper.tsx @@ -7,10 +7,10 @@ import {useLocation, useSearchParams} from "react-router-dom"; import {ReferenceCounter, ReferenceProps, useCounter} from "./layout/Reference"; import {PaperHeader} from "./PaperContent"; import {Grid, Row} from "../layout/flexbox"; -import {CanvasContainer} from "../../@orbitmines/explorer/Visualization"; import JetBrainsMono from "../layout/font/fonts/JetBrainsMono/JetBrainsMono"; import ORGANIZATIONS from "../organizations/ORGANIZATIONS"; import {PROFILES} from "../../profiles/profiles"; +import {CanvasContainer} from "../../@orbitmines/Visualization"; export type PaperProps = ReferenceProps & { header?: any // diff --git a/orbitmines.com/src/routes/papers/2023.FadiShawki.tsx b/orbitmines.com/src/routes/papers/2023.FadiShawki.tsx index 2ab230e..d3271f5 100755 --- a/orbitmines.com/src/routes/papers/2023.FadiShawki.tsx +++ b/orbitmines.com/src/routes/papers/2023.FadiShawki.tsx @@ -11,8 +11,7 @@ import {Reference} from "../../lib/paper/layout/Reference"; import {ON_INTELLIGIBILITY} from "./2022.OnIntelligibility"; import {Category, ContentFocus} from '../../profiles/FadiShawki/FadiShawki2'; import {ON_ORBITS} from "./2023.OnOrbits"; -import { Block } from '../../lib/syntax-highlighting/CodeBlock'; -import {CachedVisualizationCanvas, CanvasContainer} from "../../@orbitmines/explorer/Visualization"; +import {CanvasContainer} from "../../@orbitmines/Visualization"; const FadiShawki = () => { const profile = PROFILES.fadi_shawki; diff --git a/orbitmines.com/src/routes/papers/2023.OnOrbits.tsx b/orbitmines.com/src/routes/papers/2023.OnOrbits.tsx index e59f455..02752ac 100644 --- a/orbitmines.com/src/routes/papers/2023.OnOrbits.tsx +++ b/orbitmines.com/src/routes/papers/2023.OnOrbits.tsx @@ -13,20 +13,13 @@ import Arc from "../../lib/paper/layout/Arc"; import Link from "../../lib/paper/layout/Link"; import {renderable} from "../../lib/typescript/React"; import {Divider, Intent, Tag} from "@blueprintjs/core"; -import {CachedVisualizationCanvas, VisualizationCanvas} from "../../@orbitmines/explorer/Visualization"; import {Center} from "@react-three/drei"; import {Block} from "../../lib/syntax-highlighting/CodeBlock"; -import { - BinarySuperposition, - Continuation, - Curve, Line, Loop, - RenderedRay, torus, - Vertex -} from "../../@orbitmines/explorer/OrbitMinesExplorer"; -import {Ray} from "../../@orbitmines/explorer/Ray"; import {HorizontalLine} from "../../lib/paper/PaperContent"; import CustomIcon from "../../lib/layout/icons/CustomIcon"; import REFERENCES from "../../profiles/FadiShawki/FadiShawki"; +import { CachedVisualizationCanvas } from '../../@orbitmines/Visualization'; +import Ray from '@orbitmines/rays'; export const ON_ORBITS: Content = { reference: { From 6585bbd9dd21005cfc395d2f3104aec1211e5203 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 29 Jan 2024 18:25:08 +0100 Subject: [PATCH 133/138] 2024/01/29 - Move some old Ray stuff into OnOrbits.tsx to make it independent of the refactor for now --- _temp/OrbitMinesExplorer.tsx | 433 ---- .../src/routes/papers/2023.OnOrbits.tsx | 2028 ++++++++++++++++- 2 files changed, 2023 insertions(+), 438 deletions(-) diff --git a/_temp/OrbitMinesExplorer.tsx b/_temp/OrbitMinesExplorer.tsx index 5e36535..68f5ae3 100644 --- a/_temp/OrbitMinesExplorer.tsx +++ b/_temp/OrbitMinesExplorer.tsx @@ -15,64 +15,8 @@ export const add_ = (...a: number[][]): [number, number, number] => { } return res as [number, number, number]; } -export const add = (a: number[], b: number[]): [number, number, number] => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; export const sub = (a: number[], b: number[]): [number, number, number] => [a[0] - b[0], a[1] - b[1], a[2] - b[2]]; -export const torus = { - // Radius of the torus, from the center of the torus to the center of the tube. Default is 1. - radius: 3, color: "orange", segments: 200, tube: { width: 1, segments: 200 }, -} -export const Continuation = ( - { - color = torus.color, - radius = torus.radius, - arc = Math.PI * 2, - position - }: any) => - - -export const Loop = ( - { color = "#FFFF55", - on = "orange", - position = [0, 0, 0], - initial = position, - terminal = add(position, [0, 30, 0]), - scale = 1.5, - radius = 15, - segments = 200 - }: any -) => { - // const geometry = new TorusGeometry(radius, torus.tube.width, torus.segments, torus.tube.segments, Math.PI * 4); - // - // const vertices = geometry.getAttribute('position').array; - // const points: any = []; - // for (let i = 0; i < vertices.length; i += 3) { - // points.push([vertices[i], vertices[i + 1], vertices[i + 2]]); - // } - const points: [number, number, number][] = []; - for (let i = 0; i < segments; i++) { - const angle = ((i / segments) * Math.PI * 2) + Math.PI / 2; // STARTS AT THE TOP - const x = radius * Math.cos(angle); - const y = radius * Math.sin(angle); - - if (i > 5 && i < segments - 6) - points.push([x, y, 0]) - } - console.log(points) - - const vertex = add(position, [0, -radius, 0]); - const continuation = add(position, [0, radius, 0]); - - return - - - - -} export const Curve = ( { color = "#FFFF55", position = [0, 0, 0], @@ -99,20 +43,6 @@ export const Curve = ( } -const line = { width: 2, length: 1, color: "orange", } -export const Line = ({ start, mid, end, scale, color = line.color }: any) => - - -export const circle = { radius: 3, color: "orange", segments: 30, } -export const Vertex = ({ position, color = circle.color }: any) => - - const BinaryValue = ({ boolean, position }: any) => { if (boolean) return @@ -144,58 +74,6 @@ const BinaryValue = ({ boolean, position }: any) => { } -export const BinarySuperposition = ({ position = [0, 0, 0], scale = 1.5 }: any) => { - const halfTorus = (torus.radius + (torus.tube.width / 2)); - - const up = add(position, [0, 20 + halfTorus, 0]); - const down = add(position, [0, -20, 0]); - - const left = add(down, [-halfTorus, 0, 0]); - const right = add(down, [+halfTorus, 0, 0]); - - return <> - {/**/} - - - - - - - - - - - -} - /** * Temporary Ray visualization till the visualization is incorporated into the editor (Basically when Visualization = Ray) * @@ -391,317 +269,6 @@ export const SimpleRenderedRay = ( } } -// In principle, this should be anything, this is just for the initial setup -export const RenderedRay = ( - props: { reference: Ray.Any } & { position?: [number, number, number], initial?: [number, number, number], terminal?: [number, number, number], scale?: number, color?: string } -) => { - const { - position = [0, 0, 0], - reference, - scale = 1, - color = 'orange', - initial = add(position, [-20, 0, 0]), - terminal = add(position, [20, 0, 0]), - } = props; - const left = initial; - const right = terminal; - - if (reference.is_none() || reference.is_none()) - return <> - - const vertex = reference.self; - - const Rendered = () => { - - - const type = vertex.as_reference().type; - switch (type) { - case RayType.INITIAL: { - /** - * [ |--] - */ - if (vertex.vertex.is_none()) { - return - } else { - const possible_continuations = vertex.vertex; - - if (!possible_continuations.as_reference().is_terminal()) - return - // - // if (vertex.terminal.store.rendered) - // return <> - - return - } - } - case RayType.TERMINAL: { - if (vertex.vertex.is_none()) { - return - } else { - const possible_continuations = vertex.vertex; - - // if (!possible_continuations.as_reference().is_initial()) - // return - return <> - - // return - } - } - case RayType.REFERENCE: { - if (vertex.as_reference().is_none()) // empty reference - return - - // throw 'Not Implemented' - return - } - case RayType.VERTEX: { - const tilt = -10; // TODO; Generally should use some equivalencing in the 3d-frames for this once setup is in place (perpsective/camera) if in threejs.. - // const left = add(position, [-80 + tilt, 0, 0]); - // const right = add(position, [80 - tilt, 0, 0]); - - // const initial_side = { - // continuation: add(left, [tilt, 0, 0]), - // initial: add(left, [30 + tilt, 15, 0]), - // terminal: add(left, [30 - tilt, -15, 0]), - // - // initial_continuation: add(left, [30 + tilt * 2, 15 + 15, 0]), - // terminal_continuation: add(left, [30 - tilt * 2, -15 - 15, 0]), - // } - // const terminal_side = { - // continuation: add(right, [-tilt, 0, 0]), - // initial: add(right, [-30 + tilt, 15, 0]), - // terminal: add(right, [-30 - tilt, -15, 0]), - // - // initial_continuation: add(right, [-30 + tilt * 2, 15 + 15, 0]), - // terminal_continuation: add(right, [-30 - tilt * 2, -15 - 15, 0]), - // } - // - // const Sup = ({ position }: any) => { - // - // const left = add(position, [-20, 0, 0]); - // const right = add(position, [20, 0, 0]); - // - // return <> - // - // - // {/* Line now starts in the center of the torus tube */} - // - // {/**/} - // - // - // - // - // } - - // 55FF55 - // return <> - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // <> - // - // - // - // - // - // - // - // {/* 1C2127 quick for background */} - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // <> - // - // - // - // - // - // - // - // {/* 1C2127 quick for background */} - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - - // const left = add(position, [-20, 0, 0]); - // const right = add(position, [20, 0, 0]); - - const isVertical = position[1] !== left[1]; - - return <> - {/**/} - - {/**/} - {/**/} - {/**/} - {/**/} - - {/**/} - {/**/} - {/**/} - {/**/} - - {/**/} - - - {/* Line now starts in the center of the torus tube */} - {/*{isVertical*/} - {/* ? */} - : - {/*}*/} - - - - {/**/} - - {/**/} - - - {/*{_.sample([true, false])*/} - {/* ? */} - {/* : */} - {/*}*/} - - - - - {/*{<>*/} - {/* */} - - {/* /!* Line now starts in the center of the torus tube *!/*/} - {/* */} - - {/* /!**!/*/} - {/* /!**!/*/} - {/* */} - - {/* {_.sample([true, false])*/} - {/* ? */} - {/* : */} - {/* }*/} - - {/* */} - - {/*}*/} - - - - {/**/} - {/**/} - {/* SHOULD BE SMOOTH */} - {/**/} - - - } - } - } - - const render = - vertex.any.rendered = render; - return render; -} - diff --git a/orbitmines.com/src/routes/papers/2023.OnOrbits.tsx b/orbitmines.com/src/routes/papers/2023.OnOrbits.tsx index 02752ac..a920605 100644 --- a/orbitmines.com/src/routes/papers/2023.OnOrbits.tsx +++ b/orbitmines.com/src/routes/papers/2023.OnOrbits.tsx @@ -13,13 +13,12 @@ import Arc from "../../lib/paper/layout/Arc"; import Link from "../../lib/paper/layout/Link"; import {renderable} from "../../lib/typescript/React"; import {Divider, Intent, Tag} from "@blueprintjs/core"; -import {Center} from "@react-three/drei"; +import {CatmullRomLine, Center, Circle, QuadraticBezierLine, Torus} from "@react-three/drei"; import {Block} from "../../lib/syntax-highlighting/CodeBlock"; import {HorizontalLine} from "../../lib/paper/PaperContent"; -import CustomIcon from "../../lib/layout/icons/CustomIcon"; import REFERENCES from "../../profiles/FadiShawki/FadiShawki"; -import { CachedVisualizationCanvas } from '../../@orbitmines/Visualization'; -import Ray from '@orbitmines/rays'; +import {CachedVisualizationCanvas} from '../../@orbitmines/Visualization'; +import _ from 'lodash'; export const ON_ORBITS: Content = { reference: { @@ -2123,4 +2122,2023 @@ const OnOrbits = () => { ; } -export default OnOrbits; \ No newline at end of file +export default OnOrbits; + +const Vertex = ({ position, color = circle.color }: any) => + +// In principle, this should be anything, this is just for the initial setup +const RenderedRay = ( + props: { reference: Ray } & { position?: [number, number, number], initial?: [number, number, number], terminal?: [number, number, number], scale?: number, color?: string } +) => { + const { + position = [0, 0, 0], + reference, + scale = 1, + color = 'orange', + initial = add(position, [-20, 0, 0]), + terminal = add(position, [20, 0, 0]), + } = props; + const left = initial; + const right = terminal; + + if (reference.is_none() || reference.is_none()) + return <> + + const vertex = reference.self; + + const Rendered = () => { + + + const type = vertex.as_reference().type; + switch (type) { + case RayType.INITIAL: { + /** + * [ |--] + */ + if (vertex.vertex.is_none()) { + return + } else { + const possible_continuations = vertex.vertex; + + if (!possible_continuations.as_reference().is_terminal()) + return + // + // if (vertex.terminal.store.rendered) + // return <> + + return + } + } + case RayType.TERMINAL: { + if (vertex.vertex.is_none()) { + return + } else { + const possible_continuations = vertex.vertex; + + // if (!possible_continuations.as_reference().is_initial()) + // return + return <> + + // return + } + } + case RayType.REFERENCE: { + if (vertex.as_reference().is_none()) // empty reference + return + + // throw 'Not Implemented' + return + } + case RayType.VERTEX: { + const tilt = -10; // TODO; Generally should use some equivalencing in the 3d-frames for this once setup is in place (perpsective/camera) if in threejs.. + // const left = add(position, [-80 + tilt, 0, 0]); + // const right = add(position, [80 - tilt, 0, 0]); + + // const initial_side = { + // continuation: add(left, [tilt, 0, 0]), + // initial: add(left, [30 + tilt, 15, 0]), + // terminal: add(left, [30 - tilt, -15, 0]), + // + // initial_continuation: add(left, [30 + tilt * 2, 15 + 15, 0]), + // terminal_continuation: add(left, [30 - tilt * 2, -15 - 15, 0]), + // } + // const terminal_side = { + // continuation: add(right, [-tilt, 0, 0]), + // initial: add(right, [-30 + tilt, 15, 0]), + // terminal: add(right, [-30 - tilt, -15, 0]), + // + // initial_continuation: add(right, [-30 + tilt * 2, 15 + 15, 0]), + // terminal_continuation: add(right, [-30 - tilt * 2, -15 - 15, 0]), + // } + // + // const Sup = ({ position }: any) => { + // + // const left = add(position, [-20, 0, 0]); + // const right = add(position, [20, 0, 0]); + // + // return <> + // + // + // {/* Line now starts in the center of the torus tube */} + // + // {/**/} + // + // + // + // + // } + + // 55FF55 + // return <> + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // <> + // + // + // + // + // + // + // + // {/* 1C2127 quick for background */} + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // <> + // + // + // + // + // + // + // + // {/* 1C2127 quick for background */} + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + // + + // const left = add(position, [-20, 0, 0]); + // const right = add(position, [20, 0, 0]); + + const isVertical = position[1] !== left[1]; + + return <> + {/**/} + + {/**/} + {/**/} + {/**/} + {/**/} + + {/**/} + {/**/} + {/**/} + {/**/} + + {/**/} + + + {/* Line now starts in the center of the torus tube */} + {/*{isVertical*/} + {/* ? */} + : + {/*}*/} + + + + {/**/} + + {/**/} + + + {/*{_.sample([true, false])*/} + {/* ? */} + {/* : */} + {/*}*/} + + + + + {/*{<>*/} + {/* */} + + {/* /!* Line now starts in the center of the torus tube *!/*/} + {/* */} + + {/* /!**!/*/} + {/* /!**!/*/} + {/* */} + + {/* {_.sample([true, false])*/} + {/* ? */} + {/* : */} + {/* }*/} + + {/* */} + + {/*}*/} + + + + {/**/} + {/**/} + {/* SHOULD BE SMOOTH */} + {/**/} + + + } + } + } + + const render = + vertex.any.rendered = render; + return render; +} + +const BinarySuperposition = ({ position = [0, 0, 0], scale = 1.5 }: any) => { + const halfTorus = (torus.radius + (torus.tube.width / 2)); + + const up = add(position, [0, 20 + halfTorus, 0]); + const down = add(position, [0, -20, 0]); + + const left = add(down, [-halfTorus, 0, 0]); + const right = add(down, [+halfTorus, 0, 0]); + + return <> + {/**/} + + + + + + + + + + + +} + +const Line = ({ start, mid, end, scale, color = line.color }: any) => + + +const line = { width: 2, length: 1, color: "orange", } + +const Continuation = ( + { + color = torus.color, + radius = torus.radius, + arc = Math.PI * 2, + position + }: any) => + + +const Loop = ( + { color = "#FFFF55", + on = "orange", + position = [0, 0, 0], + initial = position, + terminal = add(position, [0, 30, 0]), + scale = 1.5, + radius = 15, + segments = 200 + }: any +) => { + // const geometry = new TorusGeometry(radius, torus.tube.width, torus.segments, torus.tube.segments, Math.PI * 4); + // + // const vertices = geometry.getAttribute('position').array; + // const points: any = []; + // for (let i = 0; i < vertices.length; i += 3) { + // points.push([vertices[i], vertices[i + 1], vertices[i + 2]]); + // } + const points: [number, number, number][] = []; + for (let i = 0; i < segments; i++) { + const angle = ((i / segments) * Math.PI * 2) + Math.PI / 2; // STARTS AT THE TOP + const x = radius * Math.cos(angle); + const y = radius * Math.sin(angle); + + if (i > 5 && i < segments - 6) + points.push([x, y, 0]) + } + console.log(points) + + const vertex = add(position, [0, -radius, 0]); + const continuation = add(position, [0, radius, 0]); + + return + + + + +} + + +/** + * Ray.ts (2024/01/18) + */ +// TODO: SHOULDNT CLASSIFY THESE? (And incorporate in Ray??) +enum RayType { + // NONE = ' ', + REFERENCE = 'REFERENCE: | ', + INITIAL = 'INITIAL: |-?', + TERMINAL = 'TERMINAL: ?-| ', + VERTEX = 'VERTEX: --|--', +} +type Boundary = RayType.INITIAL | RayType.TERMINAL; +const opposite = (boundary: Boundary): Boundary => boundary === RayType.INITIAL ? RayType.TERMINAL : RayType.INITIAL; + +type ParameterlessFunction = () => T; +type Arbitrary = (...args: any[]) => T; +type Constructor = new (...args: any[]) => T; +type ParameterlessConstructor = new () => T; + +// TODO: Merge with Arbitrary. +type Recursive = (T | Recursive)[]; +type Method = (...other: Recursive) => T; +type ArbitraryMethod = (ref: T) => Method; + +type SwitchCases< + T = Ray, + SwitchCase extends string | symbol | number = RayType, + TResult = string | ((self: T) => T) +> = { + [TCase in SwitchCase]?: TResult +} + +type Implementation = (ref: T) => T; + +/** + * https://en.wikipedia.org/wiki/Homoiconicity + */ +interface PossiblyHomoiconic> { + get self(): T; + is_reference: () => boolean + as_reference: () => T +} + +interface AbstractDirectionality { initial: Arbitrary, vertex: Arbitrary, terminal: Arbitrary } + +// TODO: better debug +type DebugResult = { [label: string]: DebugRay } +type DebugRay = { + label: string, + initial: string, + vertex: string, + terminal: string, + is_initial: boolean, + is_vertex: boolean, + is_terminal: boolean, + type: RayType, + _dirty_store: any +} + +/** + * JavaScript wrapper for a mutable value. It is important to realize that this is merely some simple JavaScript abstraction, and anything is assumed to be inherently mutable. + * + * All the methods defined here should be considered deprecated, are there to help with JavaScript implementation only. + * + * TODO: + * - Homotopy equivalence merely as some direction/reversibility constraint on some direction, ignoring additional structure (or incorporating it into the equiv) at the vertices. (Could be loosened where certain vertex-equivalences are also part of the homotopy) + * - Induced ignorance/equivalence along arbitrary rays. + * - Usual way of thinking about vertices is what the coninuations are here - phrase that somewhjere + * + * TODO: Any javascript class, allow warpper of function names around any ray, as a possible match + * TODO: All the methods defined here should be implemented in some Ray structure at some point + * + * TODO: Maybe want a way to destroy from one end, so that if other references try to look, they won't find additional structure. - More as a javascript implementation quirck if anything? + * + * TODO: Can do some workaround overloading through properties, at least for +/- + * + * TODO: Singlke keybind for now to show/hide the ray disambiguation or 'dead edges/..'/ + * + * + * + * TODO: All methods to 'step' variant - and an intuitive way to switch between modes + * - Through better Ray.___func + * - Transform all functions on Ray to that. (Perhaps use JavaScript generators by default (more intuitively?) - Just convert using JS.Generator) + * - No assumption of halting + * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence + * + * TODO: Stylistic + * - Consistency of Arbitrary vs non-arbitrary. + * - Reorder methods in a sensible way. + * + */ +class Ray // Other possibly names: AbstractDirectionality, ..., ?? + implements + PossiblyHomoiconic, + + AsyncIterable, + Iterable + // Array + // Dict +{ + // TODO: Could make a case that setting the terminal is more of a map, defaulting/first checking the terminal before additional functionality is mapped over that. + + protected _initial: Arbitrary; get initial(): Ray { return this._initial(); } set initial(initial: Arbitrary) { this._initial = initial; } + protected _vertex: Arbitrary; get vertex(): Ray { return this._vertex(); } set vertex(vertex: Arbitrary) { this._vertex = vertex; } + protected _terminal: Arbitrary; get terminal(): Ray { return this._terminal(); } set terminal(terminal: Arbitrary) { this._terminal = terminal; } + + get self(): Ray { return this.vertex; }; set self(self: Arbitrary) { this.vertex = self; } + + constructor({ initial, vertex, terminal, }: Partial> = {}) { + this._initial = initial ?? Ray.None; + this._vertex = vertex ?? this.self_reference; // TODO: None, could also self-reference the ray on which it's defining to be None. Now it's just an ignorant loop. + this._terminal = terminal ?? Ray.None; + } + + /** [ |-?] */ is_initial = (): boolean => this.is_some() && this.self.initial.is_none(); + /** [--|--] */ is_vertex = (): boolean => !this.is_initial() && !this.is_terminal(); + /** [?-| ] */ is_terminal = (): boolean => this.is_some() && this.self.terminal.is_none(); + /** [ | ] */ is_reference = (): boolean => this.is_initial() && this.is_terminal(); + /** [?-| ] or [ |-?] */ is_boundary = (): boolean => !this.is_reference() && (this.is_initial() || this.is_terminal()); // TODO: IS !This.references necessary? + + get type(): RayType { + /** [ | ] */ if (this.is_reference()) return RayType.REFERENCE; + /** [ |-?] */ if (this.is_initial()) return RayType.INITIAL; + /** [?-| ] */ if (this.is_terminal()) return RayType.TERMINAL; + // /** [ ] */ if (this.is_empty()) return RayType.NONE; + /** [--|--] */ return RayType.VERTEX; + } + + /** + * This is basically what breaks the recursive structure. Imagine a Ray like this: [|--|--|]. There are several ways of interpreting it, either there's a boolean on initial, vertex, terminal; Some 'false' value, says there's nothing there. Some true value says there's something there. - Basically an Option, ..., Maybe as in certain languages. + * + * --- + * + * Another way of interpreting a possible way of implementing it, is no matter how much more detail we would like to ask, the only thing we ever see is the same structure again (if we ignore the difference of us asking about that additional structure, that's still a possible handle on some difference). + * + * As a way of saying/.../assuming: I only 'infinitely' assume it's only this structure, "it seems to halt here". Note that this is necessarily an assumption. No guarantee of this can be made. This is necessarily an equivalence, ..., ignorance. + * + * See more: https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. + * + * --- + * + * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. + */ + is_none = (): boolean => Ray.is_orbit(this.self, this.self.self); + + /** + * Tries for "global coherence" - since we probably can't actually do that, practically this just means self-reference, were no change is assumed... + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. + */ + static is_orbit = (a: Ray, b: Ray) => a === b; // is, ..., appears equal. + protected self_reference = () => this; + + is_some = (): boolean => !this.is_none(); + + /** + * Can be used to override default dereference behavior. + * + * TODO: This should probably be configurable on a more global setting. + * + * TODO: Difference between this.self and this.self.self.as_reference is??? + */ + get dereference() { return this.self.self.as_reference(); } + + // /** + // * Moves `this.self` and `this.self.self` to a new line. + // * + // * [ |--] this.self ----- this.self.self [--|--] + // * ______ (<- initial pointer) + // */ + // as_initial = (): Ray => { + // if (this.is_none()) { + // throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); + // } + // if (this.dereference.is_none()) { + // // TODO: Need some intuition for this check + // const vertex = this.___as_vertex(); + // + // if (vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // return vertex.follow(Ray.directions.previous); + // } + // + // const [terminal_vertex, initial_vertex] = this.___as_vertices(); + // + // if (initial_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // if (terminal_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // initial_vertex.compose(terminal_vertex); + // + // // TODO BETTER DEBUG + // + // return initial_vertex.follow(Ray.directions.previous); + // } + // /** + // * Moves `this.self` and `this.self.self` to a new line. + // * + // * [ |--] this.self.self ----- this.self [--|--] + // * _____ (<- terminal pointer) + // */ + // as_terminal = (): Ray => { + // if (this.is_none()) { + // throw new PreventsImplementationBug('Should be implemented at some point ; Just return an empty vertex'); + // } + // if (this.dereference.is_none()) { + // // TODO: Need some intuition for this check + // const vertex = this.___as_vertex(); + // + // if (vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // return vertex.follow(); + // } + // + // const [initial_vertex, terminal_vertex] = this.___as_vertices(); + // + // if (initial_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // if (terminal_vertex.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(); + // + // initial_vertex.compose(terminal_vertex); + // + // // TODO BETTER DEBUG + // + // return terminal_vertex.follow(); + // } + // private ___as_vertices = (): [Ray, Ray] => { + // if (!Ray.is_orbit(this.self, this.self.self.self)) + // throw new PreventsImplementationBug('Is there a use-case for this? Probably not?'); //TODO + // + // // TODO NOTE: THE ORDER OF `this.self` first matters here. + // return [this.self.___as_vertex(), this.___as_vertex()]; + // } + // private ___as_vertex = (): Ray => { + // const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + // + // // this.self.self = vertex.self.as_arbitrary(); + // // vertex.self.self = this.self.as_arbitrary(); + // + // // return this.___ignorantly_equivalent(Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' })); + // + // return this.___ignorantly_equivalent(vertex); + // } + private ___ignorantly_equivalent = (ref: Ray): Ray => { + this.self.self = ref.self.as_arbitrary(); + ref.self.self = this.self.as_arbitrary(); + + return ref; + } + + /** [ ] */ static None = () => new Ray({ }).o({ }); + /** [--?--] */ static vertex = (value: Arbitrary = Ray.None) => { + /** [ ] */ const vertex = Ray.None(); + /** [-- ] */ vertex.initial = vertex.___empty_initial(); + /** [ ? ] */ vertex.vertex = value; + /** [ --] */ vertex.terminal = vertex.___empty_terminal(); + + /** [--?--] */ return vertex; + } + /** [ |-?] */ static initial = () => Ray.vertex().initial; + /** [?-| ] */ static terminal = () => Ray.vertex().terminal; + + // TODO; Temp placeholders for now - & BETTER DEBUG + ___empty_initial = () => new Ray({ vertex: Ray.None, terminal: this.as_arbitrary() }).o({ debug: 'initial ref'}).as_arbitrary(); + ___empty_terminal = () => new Ray({ vertex: Ray.None, initial: this.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary(); + + /** A ray whose vertex references this Ray (ignorantly - 'this' doesn't know about it). **/ + /** [?????] -> [ | ] */ as_reference = (): Ray => new Ray({ vertex: this.as_arbitrary() }); + + // TODO: Difference between () => this & this.as_arbitrary , relevant for lazy/modular/ignorant structures etc.. + as_arbitrary = (): Arbitrary => () => this; + + /** + * TODO : COMPOSE EMPTY AS FIRST ELEMENT: + * if (initial.is_none()) { + * // 'Empty' vertex from this perspective. + * + * initial.vertex = terminal.as_arbitrary(); + * console.log('first element'); + * return terminal; + * } + */ + + // TODO: Test if references hold after equivalence/composition... + + + // TODO: Returns the ref, since it still holds the information on how they're not the same??? - Need some intuitive way of doing this? + // TODO a.equivalent(b).equivalent(c), in this case would be [[a, b]].equivalent(c) not [a, b, c].equivalent ??? + + // TODO: Should do, one timesteap ahead, collapse one reference, and then recursively call continues_with on the vlaue at the reference, until it yields something. + + // TODO AS += through property + // TODO: Generally, return something which knows where all continuations are. + // @alias('merge, 'continues_with', 'compose') + /** + * Compose as "Equivalence at Continuations": (can usually be done in parallel - not generally) + * - `A.compose(B)` = `(A.TERMINAL).equivalent(B.INITIAL)` + * - `A.compose(B).compose(C)` = `(A.TERMINAL).equivalent(B.INITIAL) & (B.TERMINAL).equivalent(C.INITIAL)` + * + * Another interesting connection: + * - `A.compose(B).compose(C)` = `(A.equivalent(B).equivalent(C)).dereference.(MISSING ALL FUNC).compose` + * + * @see "Continuations as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence + */ + static compose = Ray.___func(ref => { + let { initial, terminal} = ref.self; + + if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) + throw new PreventsImplementationBug(); + + // ${[...initial.self.initial.as_reference().all().js]} + if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) { + throw new PreventsImplementationBug(`[${initial.type}] - [${terminal.type}] - only composing vertices for now (${initial.self.initial.any.js} -> ${terminal.self.terminal.any.js})`); + } + + initial.follow().equivalent(terminal.follow(Ray.directions.previous)); + + // return ref; TODO + return terminal; + }); + compose = Ray.compose.as_method(this); + + // TODO: Cleanup + /** + * Equivalence as "Composing Vertices": "TODO: Is this right?: Equivalence at Continuations, inside a Vertex, is parallel composition, from the perspective of the usual direction defined at the Vertex (not generally parallel)" + * - `A.equivalent(B)` = `A.as_vertex().compose(B.as_vertex())` + * - `A.equivalent(B).equivalent(C)` = `A.as_vertex().compose(B.as_vertex()).compose(C.as_vertex())` + * + * An equivalence is best understood as the drawing of a single line between two things. Where those two things might have arbitrary structure around them, but we're not checking the (non-)existence of that structure. And thus: + * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. (or: Changes of an equivalence are only applied locally, which could have global effects, but this isn't necessarily obvious). + * + * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies + */ + static equivalent = Ray.___func(ref => { + let { initial, terminal} = ref.self; + + /** + * The simplest case, is where both sides are only aware of themselves (on .vertex). The only thing we need to do is turn an Orbit, to an Orbit which repeats every 2 steps, the intermediate step being the other thing. + * + * Or in textual terms something like: + * - A single Orbit: `(A.self = A) | (B.self = B)` (i.e. A.is_none && B.is_none) + * - To: `(A.self = B) | (B.self = A)` + * + * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. + */ + const ignorant_equivalence = (): Ray => { + return initial.___ignorantly_equivalent(terminal); + } + + // 2x Ray.None -> Turn into 2 empty references, referencing each-other. + if ( + initial.dereference.is_none() && terminal.dereference.is_none() + && !(initial.type === RayType.VERTEX && terminal.type === RayType.VERTEX) + ) { + // throw new PreventsImplementationBug(`${initial.type} / ${terminal.type}`) + return ignorant_equivalence(); + } + + // Two structures, which have `ref.self = Ray.None` -> Turn into two structures which are on a line in between them. + if (initial.dereference.is_none()) { + const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + vertex.self.self = initial.self.as_arbitrary(); + initial.self.self = vertex.self.as_arbitrary(); + + // initial.equivalent(terminal); + // return terminal; + } + if (terminal.dereference.is_none()) { + const vertex = Ray.vertex().o({ js: '___as_vertex' }).as_reference().o({ js: '___as_vertex.#' }); + vertex.self.self = terminal.self.as_arbitrary(); + terminal.self.self = vertex.self.as_arbitrary(); + + // initial.equivalent(terminal.___as_vertex()); + // return terminal; + } + + if ( + initial.dereference.type !== RayType.VERTEX + || terminal.dereference.type !== RayType.VERTEX + || initial.dereference.self === initial.self + || terminal.dereference.self === terminal.self + ) { + throw new PreventsImplementationBug('wut') + } + + if (initial.follow().type !== RayType.TERMINAL || terminal.follow(Ray.directions.previous).type !== RayType.INITIAL) { + throw new PreventsImplementationBug('wut2') + } + + // if (terminal.self.any.js === 'D') + // throw new PreventsImplementationBug(); + + initial.dereference.compose(terminal.dereference); + + return terminal; + + // initial.dereference.compose() + // return terminal; + }); + equivalent = Ray.equivalent.as_method(this); + + // static equivalent = Ray.___func(ref => { + // let { initial, terminal} = ref.self; + // + // /** + // * The simplest case, is where both sides are only aware of themselves (on .vertex). The only thing we need to do is turn an Orbit, to an Orbit which repeats every 2 steps, the intermediate step being the other thing. + // * + // * Or in textual terms something like: + // * - A single Orbit: `(A.self = A) | (B.self = B)` (i.e. A.is_none && B.is_none) + // * - To: `(A.self = B) | (B.self = A)` + // * + // * Basically turns `A` into a reference to `B`, and `B` into a reference to `A`. + // */ + // const ignorant_equivalence = (): Ray => { + // return initial.___ignorantly_equivalent(terminal); + // } + // + // // 2x Ray.None -> Turn into 2 empty references, referencing each-other. + // if (initial.is_none() && terminal.is_none()) + // return ignorant_equivalence(); + // + // // Two structures, which have `ref.self = Ray.None` -> Turn into two structures referencing each-other. + // if (initial.dereference.is_none() && terminal.dereference.is_none()) + // return ignorant_equivalence(); + // + // if ( + // (initial.is_vertex() && terminal.is_boundary()) + // || (terminal.is_vertex() && initial.is_boundary()) + // ) { + // throw new NotImplementedError(`Parallel composition: TODO`); + // } + // + // /** + // * - Splits the 'initial' side's vertex, into an iterable one, and returns a pointer to the initial side of that iterator. + // * + // * - Similarly, we do the opposite for the terminal, returning the terminal side of that iterator. + // * + // * - Then we're left with the 'beginning' of one iterator, and the 'end' of the other. And the only thing that's left to do, is draw a simple (ignorant) equivalence between the two. (Basically call this function again, and call {ignorant_equivalence}). + // * TODO: This could also be a line with some debug information. + // */ + // const a = initial.as_terminal(); + // const b = terminal.as_initial(); + // + // if (a.type !== RayType.TERMINAL) + // throw new PreventsImplementationBug(); + // if (b.type !== RayType.INITIAL) + // throw new PreventsImplementationBug(); + // + // if (!a.self.self.is_none()) + // throw new PreventsImplementationBug(`${b.self.self.any.js}`); + // if (!b.self.self.is_none()) + // throw new PreventsImplementationBug(`${b.self.self.any.js}`); + // + // a.equivalent(b); + // + // const ret = terminal; + // + // if (ret.type !== RayType.VERTEX) + // throw new PreventsImplementationBug(`${ret.type}`); + // + // return ret; + // }); + // equivalent = Ray.equivalent.as_method(this); + + // zip also compose??? + // [a, b, c] zip [d, e, f] zip [g, h, i] ... + // [[a,d,g],[b,e,h],[c,f,i]] + static zip = Ray.___func(ref => { + let { initial, terminal } = ref.self; + + if (initial.as_reference().type !== RayType.REFERENCE || terminal.as_reference().type !== RayType.REFERENCE) + throw new PreventsImplementationBug('TODO: Implement'); + + if (initial.type !== RayType.VERTEX || terminal.type !== RayType.VERTEX) + throw new PreventsImplementationBug('TODO: Implement'); + + throw new NotImplementedError(); + // initial.traverse() + // return new Ray({ + // + // }); + }); + zip = Ray.zip.as_method(this); + + // pop = (): Ray => { + // this.last().previous().all.terminal = (ref) => ref.___empty_terminal(); + // } + pop = (): Ray => this.___primitive_switch({ + [RayType.VERTEX]: () => { + const previous_vertex = this.self.initial.follow(Ray.directions.previous); + + if (this.is_none()) { + return this; // TODO; Already empty, perhaps throw + } + + return previous_vertex.___primitive_switch({ + [RayType.VERTEX]: () => { + console.log(previous_vertex) + // TODO: NONHACKY + + previous_vertex.self.terminal = new Ray({ vertex: Ray.None, initial: previous_vertex.self.as_arbitrary() }).o({ debug: 'terminal ref'}).as_arbitrary() + return previous_vertex; + } + }); + } + }); + + + // static sn = (step: Implementation): { + // as_method: ArbitraryMethod + // } => { + // + // return { + // as_method: Ray.___func(step).as_method + // } + // } + + /** + * Constructs a function accepting arbitrary structure based on one implementation of it. + * + * TODO: Is there some equivalent of this in computer science??? category theory?? + * + * a.compose(b).compose(c) = [a, b, c].compose = abc.compose = [[a1, a2], b, c].compose = [[a1, a2], b, [c1, c2]].compose = [[a1, [[[a2]]], [[[[]]], []]], b, [[[]], [], [c]]].compose = ... + */ + static ___func( + step: Implementation, + ): { + as_method: ArbitraryMethod + } { + return { + + /** + * Puts the Ray this is called with on a new Ray [initial = ref, ???, ???]. Then it places any structure it's applying a method to, on the terminal of this new Ray [initial = ref, ???, terminal = any] + */ + as_method: (ref: Ray): Method => (...any: Recursive): Ray => { + if (any === undefined || any.length === 0) + return step(ref); + + // TODO: This can be much better... + const first = (recursive?: Recursive): Ray | undefined => { + if (recursive === undefined) return; + // if (_.isObject(recursive)) return recursive as unknown as Ray; + + for (let r of recursive) { + if (r === undefined) continue; + if (_.isObject(r)) return r as unknown as Ray; + + // if (r instanceof Ray) + // throw new PreventsImplementationBug(); + + // @ts-ignore + const _first = first(r); + if (_first) + return _first; + } + } + + const _first = first(any); + + if (_first === undefined) + return step(ref); + + const pointer = new Ray({ + initial: () => ref, + terminal: () => _first + }); + + return step(pointer); + + // TODO: ANY CASE + // if (any.length === 1) { + // } + } + } + } + + /** + * Helper methods for commonly used directions + * + * TODO: Link to step-wise walk as any function - lazy, not traversing certain paths, etc.. (for last/..) + */ + static directions = { + next: (ref: Ray) => ref.self.terminal.as_reference(), + previous: (ref: Ray) => ref.self.initial.as_reference(), + } + + // TODO: Nicer one? ; Differentiate between ".next" and just "follow the pointer" ? + follow = (step: Implementation = Ray.directions.next): Ray => { + // let pointer = new Ray({ + // initial: () => this, + // terminal: () => step(this), + // }); TODO USE POINTER? + + return step(this); + } + + /** + * .next + */ + next = (step: Implementation = Ray.directions.next): Ray => { + // for (let next of this.___next({step})) { + // + // // return next; + // } + // + // return Ray.None(); + let pointer = new Ray({ + initial: () => this, + terminal: () => step(this), + }); + + pointer = pointer.step().step(); + + if (pointer.terminal.type !== RayType.VERTEX) + throw new NotImplementedError(`${pointer.terminal.type} / ${pointer.terminal.self.any.js}`); + + return pointer.terminal; + + // return Ray.___next(Ray.directions.next)(this); + } + has_next = (step: Implementation = Ray.directions.next): boolean => this.next(step).is_some(); + // @alias('end', 'result', 'back') + last = (step: Implementation = Ray.directions.next): Ray => { + const next = this.next(step); + return next.is_some() ? next.last(step) : this; + } + /** + * .previous (Just .next with a `Ray.directions.previous` default) + */ + previous = (step: Implementation = Ray.directions.previous): Ray => this.next(step); + has_previous = (step: Implementation = Ray.directions.previous): boolean => this.has_next(step); + // @alias('beginning', 'front') + first = (step: Implementation = Ray.directions.previous): Ray => this.last(step); + + // TODO: I Don't like this name, but it needs to get across that any equivalency, or any equivalency check for that necessarily, is local. And I want more equivalences, I run more of this method. + // TODO: For chyp used to compare [vtype, size] as domains, just type matching on the vertex. + is_vertex_equivalent = (b: Ray) => { + // TODO; in the case of a list, each individually, again, additional structure... + } + // TODO: Ignore the connection between the two, say a.equiv(b) within some Rule [a,b], ignore the existing of the connection in the Rule? What does it mean not to??? + + // TODO: Whether the thing is referenced on the vertex: do their vertices have some connection onm this direction? + is_equivalent = (b: Ray): boolean => { return false; } // TODOl: Current references assume you can't go inside vertex.. + // TODO implement .not?? + + get count(): Ray { return Number(this.as_array().length); } + + // TODO; Could return the ignorant reference to both instances, or just the result., .. + + /** + * TODO: Need more control over the (non-/)lazyness of copy. + * + * - The problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. + * + * - Additionally, a copy necessarily has some non-redundancy to it: + * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy + */ + // @alias('duplicate') + copy = (): Ray => { + // return this.self.as_reference(); // Copies the reference? + throw new NotImplementedError(); + + // const copy = new Ray({ + // initial: this.self._initial().as_reference().none_or(ref => ref.copy()).as_arbitrary(), + // vertex: this.self._vertex().as_reference().none_or(ref => ref.copy()).as_arbitrary(), + // }).o({ ___dirty_copy_buffer: {} }); + // // copy._initial = () => copy.any.___dirty_copy_buffer._initial ??= this.self._initial().as_reference().copy(); + // // copy._vertex = () => copy.any.___dirty_copy_buffer._vertex ??= this.self._vertex().as_reference().copy(); + // // copy._terminal = () => copy.any.___dirty_copy_buffer._terminal ??= this.self._terminal().as_reference().copy(); + // + // + // // TODO: Doesn't copy .any + // + // return copy.as_reference(); + } + + // none_or = (arbitrary: Implementation): Ray => this.is_none() ? Ray.None() : arbitrary(this); + + // @alias('converse', 'opposite', 'swap') + get reverse(): Ray { + const copy = this;//TODO.copy(); + + // TODO: Do we do this lazy by default? Just using refs??? - Or abstract this elsewhere to decide what to do + const swap = copy.initial; + copy.initial = copy.terminal.as_arbitrary(); + copy.terminal = swap.as_arbitrary(); + // TODO: This doesn't actually work + + return copy; + } + + /** + * TODO - Better 'value' here. (Use JS.Any??) + * + * TODO: All these should accept Ray values. + * + * .size, since .length is reserved by JavaScript. + * TODO: .size could be more tensor-like, arbitrary lengths.. + */ + // @alias('length', 'of_length') + static size = (of: number, value: any = undefined): Ray => { + let ret: Ray | undefined; + let current: Ray | undefined; + // TODO: Actual good implementation: Should be lazy + for (let i = 0; i < of; i++) { + const vertex = Ray.vertex().o({js: value}).as_reference(); + + if (!ret) { + current = ret = vertex; + } else { + current = current?.compose(vertex); + } + } + + if (!ret) + return Ray.None(); + + return ret; + } + static at = (index: number, of: number, value: any = undefined): Ray => { + return Ray.size(of, value).at(index); + } + /** + * Just uses length/size for permutation. TODO: More complex permutation/enumeration implementation should follow at some point. (@see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=One%20of%20them%20could%20even%20be%20putting%20both%20our%20points%20on%20our%20selection for an example) + * + * @see "Combinatorics as Equivalence": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Combinatorics%20%2D%20Combinatorics%20as%20Equivalence + */ + static permutation = (permutation: number | undefined, of: number): Ray => Ray.at( + // In the case of a bit: 2nd value for '1' (but could be the reverse, if our interpreter does this) + permutation ?? 0, + // In the case of a bit: Either |-*-| if no bit or |-*->-*-| if a bit. + permutation === undefined ? 1 : of + ) + + at = (steps: number | Ray | Arbitrary): Ray => { + if (!is_number(steps)) + throw new NotImplementedError('Not yet implemented for Rays.'); + + // TODO: Actual good implementation - also doesn't support modular like this + const array = [...this.traverse( + steps < 0 ? Ray.directions.previous : Ray.directions.next + )]; + + steps = Math.abs(steps); + + return array.length > steps && steps >= 0 ? ( + array[steps] ?? Ray.None() // TODO FIX: Probably a JavaScript quirck with some weird numbers, just failsafe to None. + ) : Ray.None(); + } + + // const hexadecimal = (hexadecimal?: string): Arbitrary> => permutation(hexadecimal ? parseInt(hexadecimal, 16) : undefined, 16); + + // TODO: Should give the program that does the mapping, not the result, and probably implemented as 'compile/traverse' + map = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + // filter = (mapping: (ray: Ray) => Ray | any): Ray => { throw new NotImplementedError(); } + get clear(): Ray { throw new NotImplementedError(); } + + // TODO: Generalize these functions to: + // + // TODO: +default, in the case of Initial/Terminal = Ray.None, to which the default sometimes is nothing. Or in the case of min/max it's 0. + + + // TODO: being called min.x needs to return the min value within that entire structure. + + // [this.vertices().x.max(), this.edges().x.max()].max() + // [this.vertices().x.min(), this.edges().x.max()].max() + // TODO: Indicies not corresponding the the directionality defined, are probably on another abstraction layer described this way. More accurately, they're directly connected, and on a separate layer with more stuff in between... + get index(): Ray { throw new NotImplementedError(); } + // TODO: Can probably generate these on the fly, or cache them automatically + min = (_default: 0): Ray => { throw new NotImplementedError(); } + max = (_default: 0): Ray => { throw new NotImplementedError(); } + + // TODO: FIND OUT IF SOMEONE HAS A NAME FOR THIS + // apply = (func: Ray) => { + + // TODO: Combine into generalized [x, min/max()] - preserve terminal/initial structure + // TODO: ray#apply. + // TODO: FROM COMPOSER + /** + * const func = [min(), '', max()] + * + * const [min_x, max_x] = [ + * // Compute the min x-coordinate of the edges and vertices in the other graph. + * compose.terminal.x.min(), // min_other + * + * // Compute the max x-coordinate of the edges and vertices in this graph. + * compose.initial.x.max(), // max_self + * ] + */ + // } + + // ___compute = () + + *traverse(step: Implementation = Ray.directions.next): Generator { + // TODO: Also to ___func?? + + if (this.type !== RayType.VERTEX) + throw new NotImplementedError(`[${this.type}]`); + + yield *this.___next({step}); + } + + static pointer = (initial: Ray, step: Implementation): Ray => new Ray({ + initial: () => initial, + terminal: () => step(initial) + }); + + private next_pointer = (step: Implementation) => { + const { self: history, terminal: current } = this; + + return new Ray({ + initial: current.as_arbitrary(), + vertex: history.as_arbitrary(), + terminal: () => current.follow(step) + }); + }; + + /** + * VERTEX (current) + * | + * v + * + * ? <-- Pointer B + * [--| ] <-- INITIAL/TERMINAL (previous) + * ? <-- Pointer A + */ + private branch = (): [Ray, Ray] => { + const { initial: previous, terminal: current } = this; + + if (!previous.is_boundary()) + throw new PreventsImplementationBug('Only branching off INITIAL/TERMINAL -> VERTEX for now.'); + if (current.type !== RayType.VERTEX) + throw new PreventsImplementationBug('Only branching off INITIAL/TERMINAL -> VERTEX for now.'); + + return [ + this.next_pointer(Ray.directions.previous), + this.next_pointer(Ray.directions.next) + ]; + } + + *___next({ + step = Ray.directions.next, + } = {}): Generator { + for (let pointer of this.___traverse({step})) { + + // TODO: You can do this non-locally with a pass over the history. This way it's local, but we''ll have to find a good example of why this might not go that well. (As this would match to any empty vertices, and maybe more) + + // TODO: Could also check for none.. + const { initial: previous, terminal: current } = pointer; + + if (previous.is_vertex() && !Ray.is_orbit(previous.self, current)) { + yield pointer.initial; + } + } + } + *___map(map: (vertex: Ray) => T, { + step = Ray.directions.next, + } = {}): Generator { + for (let vertex of this.___next({step})) { + yield map(vertex); + } + } + + /** + * TODO: Not happy with this... + */ + *___traverse({ + step = Ray.directions.next, + should_branch = (pointer: Ray) => { + const { initial: previous, terminal: current } = pointer; + return previous.is_boundary() && current.is_vertex() && Ray.is_orbit(current.self, previous); + }, + branch = (pointer: Ray): [Ray, Ray] => pointer.branch(), + filter = (pointer: Ray): boolean => true, + next = (pointers: Ray[]): Ray => pointers[0], + remove = (pointers: Ray[], pointer: Ray) => delete pointers[0], + } = {}): Generator { + const pointers: Ray[] = [ + Ray.vertex(Ray.pointer(this, step).as_arbitrary()) + ]; // TODO COuld be a ray; + + while (true) { + + const ref = next(pointers); + if (ref === undefined) { + // TODO: Could just keep trying... + break; + } + let { self: pointer } = ref; + + if (!filter(pointer)) { + remove(pointers, pointer); + continue; + } + + yield pointer; + + pointer = pointer.step(); + + if (pointer.terminal.is_none()) { + remove(pointers, pointer); + continue; + } + + if (should_branch(pointer)) { + const [a, b] = branch(pointer); + + ref.self = a.as_arbitrary(); + pointers.push(Ray.vertex(b.as_arbitrary())); + } else { + ref.self = pointer.as_arbitrary(); + } + } + } + + /** + * + * + * TODO: switch/match Should be abstracted into Ray? + */ + static step = (ref: Ray) => { + const { initial } = ref; + + /** + * Should return vertex, for one possible next step + * Initial for many + * Terminal for none + * Reference for ??? + */ + + /** + * Dereferencing is likely in many cases quickly subject to infinite stepping. + * + * REFERENCE -> Dereference (this.self.self) + * INITIAL/INITIAL -> Dereference (this.self.terminal) + * TERMINAL/TERMINAL -> Dereference (this.self.initial) + * VERTEX/VERTEX -> ??? + * + * - Could be that this means that there's no continuation, a self-reference defined here, or it's some mechanism of halting. + * + * - TODO: Simple example of infinitely finding terminals, or a reference to 'nothing - infinitely'. + * - TODO: Could return both dereference sides as possible options + */ + + const next_pointer = (terminal: Ray, next: Arbitrary) => new Ray({ + initial: () => terminal, + vertex: () => ref, + terminal: next, + }); + + /** + * INITIAL/TERMINAL -> possible previous - TERMINAL.self.initial (pass to step) + * TERMINAL/INITIAL -> possible next - INITIAL.self.terminal (pass to step) + */ + const follow_direction = (terminal: Ray): Ray => next_pointer(terminal, () => terminal.___primitive_switch({ + [RayType.INITIAL]: Ray.directions.next, + [RayType.TERMINAL]: Ray.directions.previous, + })); + + const dereference = (terminal: Ray) => next_pointer(terminal, () => terminal.dereference); + + /** + * TERMINAL -> VERTEX (next: VERTEX -> INITIAL) + * INITIAL -> VERTEX (next: VERTEX -> TERMINAL) + */ + const arbitrary_continuations = (terminal: Ray): Ray => next_pointer(terminal, () => initial.___primitive_switch({ + [RayType.INITIAL]: (initial) => Ray.directions.next(terminal), + [RayType.TERMINAL]: (initial) => Ray.directions.previous(terminal), + })); + + const boundary = (boundary: Boundary) => (terminal: Ray): Ray => terminal.___primitive_switch({ + + /** + * Many possible continuations (from the perspective of initial = TERMINAL) + * + * From something, we arrived at some TERMINAL/INITIAL, which at its `.self`, holds a VERTEX. + * [ ? ] + * [--|--][--| ] <-- ref superposed with ref.self + * [ ? ] + */ + [RayType.VERTEX]: arbitrary_continuations, + + /** + * A possible continuation + * + * (INITIAL -> TERMINAL) + * (TERMINAL -> INITIAL) + */ + [boundary]: follow_direction, + [opposite(boundary)]: follow_direction, + + [RayType.REFERENCE]: dereference, + }); + + return initial.___primitive_switch({ + + /** + * VERTEX -> VERTEX + * TODO Could be an ignorant continuation (as in, the terminal does not have the initial vertex on its .initial). Or you could interpret this as saying, oh this should be a vertex, no information about the continuation definition in between? + * + * VERTEX -> TERMINAL + * If we're going in the terminal direction (from the perspective of the initial = VERTEX) + * [--|--][--| ] <-- (VERTEX -> TERMINAL) + * + * VERTEX -> INITIAL + * If we're going in the initial direction (from the perspective of the initial = VERTEX) + * [ |--][--|--] <-- (VERTEX -> INITIAL) + * + * VERTEX -> REFERENCE + * TODO ??? + */ + [RayType.VERTEX]: (initial) => dereference(ref.terminal), + + [RayType.INITIAL]: (initial) => boundary(RayType.INITIAL)(ref.terminal), + [RayType.TERMINAL]: (initial) => boundary(RayType.TERMINAL)(ref.terminal), + + [RayType.REFERENCE]: dereference, + }); + } + step= Ray.___func(Ray.step).as_method(this); + + // TODO; Maybe replace switch with 'zip'?, What are the practical differences? + protected ___primitive_switch = (cases: SwitchCases): Ray => { + const _case = cases[this.type]; + + if (_case === undefined || _.isString(_case)) + { // @ts-ignore + throw new PreventsImplementationBug(_case ?? `Unhandled switch case; [${this.type}]`); + } + + return _case(this); + } + + /** + * JavaScript, possible compilations - TODO: Could have enumeratd possibilities, but just ignore that for now. + */ + // JS.AsyncGenerator + async *[Symbol.asyncIterator](): AsyncGenerator { yield *this.traverse(); } + // JS.Generator + *[Symbol.iterator](): Generator { yield *this.traverse(); } + // JS.AsyncGenerator + as_async_generator = (): AsyncGenerator => this[Symbol.asyncIterator](); + // JS.AsyncIterator + as_async_iterator = (): AsyncIterator => this.as_async_generator(); + // JS.Iterator + as_generator = (): Generator => this[Symbol.iterator](); + // JS.AsyncIterator + as_iterator = (): Iterator => this.as_generator(); + // JS.Array + as_array = (): Ray[] => [...this]; + // JS.String + toString = (): string => this.as_string(); + as_string = (): string => this.as_array().map(ref => ref.any.js).join(','); // TODO: PROPER + + as_int = (): number => { throw new NotImplementedError(); } + as_number = this.as_int; + + /** + * + * TODO: + * - This needs something much smarter at some point... + */ + all = (step: Implementation = Ray.directions.next): { [key: string | symbol]: Ray } & any => { + return new Proxy(this, { + + get(self: Ray, p: string | symbol, receiver: any): any { + + return self.___map(ref => ref.any[p], {step}); + }, + + /** + * Can't overload things like '-=' for anything but things that return numbers... ; So just apply a general function instead. + */ + set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { + for (let ref of self.___next({step})) { // TODO; This needs to either be dynamically, or just a simple shut-off for circular ones. + ref.any[p] = is_function(newValue) ? newValue(ref.any[p]) : newValue; + } + + return true; + }, + + + deleteProperty(self: Ray, p: string | symbol): boolean { + throw new NotImplementedError(); + + return true; + } + // TODO: What do these other methods on Proxy do??? + }); + + } + + /** + * Move to a JavaScript object, which will handle any complexity of existing JavaScript objects, and allows one to abstract any values contained in the {vertex} to the usual JavaScript interface. - More usual to how one thinks about functions, ..., properties. + */ + get any(): { [key: string | symbol]: Ray } & any { return this.self.proxy(); } + get ___any(): { [key: string | symbol]: Ray } & any { return this.proxy(); } + cast = (): T => { throw new NotImplementedError(); } // TODO this.proxy(); + + /** + * Used for chaining JavaScript-provided properties + * + * TODO: DOESNT FOLLOW .ANY PATTERN? + */ + o = (object: { [key: string | symbol]: any }): Ray => { + _.keys(object).forEach(key => this.proxy()[key] = object[key]); // TODO: Can be prettier, TODO: map to Ray equivalents and add to vertices.. + return this; + } + + // All these are dirty + o2 = ({ initial, vertex, terminal }: any): Ray => { + if (initial) this.initial.o(initial); + if (vertex) this.o(vertex); + if (terminal) this.terminal.o(terminal); + + return this; + } + + protected property = (property: string | symbol, _default?: any): any => this.any[property] ??= (_default ?? Ray.None()); // TODO: Can this be prettier?? + + protected _proxy: any; + protected _dirty_store: { [key: string | symbol]: object } = {} + protected proxy = (constructor?: ParameterlessConstructor): T & { [key: string | symbol]: Ray } => { // TODO: + // TODO: IMPLEMENT SPLAT... {...ray.any} + return this._proxy ??= new Proxy(this, { + + get(self: Ray, p: string | symbol, receiver: any): any { + + // throw new NotImplementedError(); + return self._dirty_store[p]; + // return self.as_arbitrary(); + }, + set(self: Ray, p: string | symbol, newValue: any, receiver: any): boolean { + // throw new NotImplementedError(); + self._dirty_store[p] = newValue; + + return true; + }, + + deleteProperty(self: Ray, p: string | symbol): boolean { + if (!(p in self._dirty_store)) { + return false; + } + + delete self._dirty_store[p]; + return true; + } + // TODO: What do these other methods on Proxy do??? + }) as T; + } + + /** + * + * - Don't assume we can track back any reference to this thing. Just destroy it, set everything to None. And let anything else deal with the consequences of the deletion. + * + * TODO: + * - Could lazily try to find references. + * - Implement on proxy for 'delete ray' + */ + delete = (): Ray => { + this.self.initial = Ray.None; + this.self.self = this.self.self_reference; + this.self.terminal = Ray.None; + // TODO: REMOVE THESE + this.self._proxy = undefined; + this.self._dirty_store = {}; + + // Removes the current reference to it. + this.self = this.self_reference; + + return this; + } + + //TODO USED FOR DEBUG NOW + move = (func: (self: Ray) => Ray, memory: boolean, Interface: Ray): Ray => { + const target_ray = func(this.self); + + const target = target_ray.as_reference().o({ + ...this._dirty_store, + position: + target_ray.any.position + ?? this.any.position + ?? Ray.POSITION_OF_DOOM + }); + console.log('move', `${this.self.label.split(' ')[0]} -> ${target.self.label.split(' ')[0]}`); + + if (memory) { + if (!target_ray.any.traversed) { + Interface.___any.rays.push(target); + target_ray.any.traversed = true; + } + } else { + Interface.___any.rays = [target]; + } + + return target; + } + + static POSITION_OF_DOOM = [0, 100, 0] + + // TODO: Abstract away as compilation + render_options = (Interface: Ray): Required => { + return ({ + position: + this.any.position + ?? (this.is_none() ? Ray.POSITION_OF_DOOM : Ray.POSITION_OF_DOOM), + rotation: + this.any.rotation + ?? [0, 0, 0], + scale: + this.any.scale + ?? (this.is_none() ? 1.5 : 1.5), + color: + (Ray.is_orbit(Interface.___any.selection.self, this.self) && Interface.___any.cursor.tick) ? '#AAAAAA' // TODO: Should do lines as well, line render should prefer based on level of description.. (flat line only vertices, then render for the vertex?) + : ( + this.any.color + ?? (this.is_none() ? 'red' : { + [RayType.VERTEX]: 'orange', + [RayType.TERMINAL]: '#FF5555', + [RayType.INITIAL]: '#5555FF', + [RayType.REFERENCE]: '#555555', + }[this.type] + ) + ) + }); + } + + ___dirty_all(c: Ray[]): Ray[] { + if (c.filter(a => a.label === this.label).length !== 0) { + return c; + } + + c.push(this); + + if (this.initial.as_reference().is_some()) + this.initial.___dirty_all(c); + if (this.vertex.as_reference().is_some()) + this.vertex.___dirty_all(c); + if (this.terminal.as_reference().is_some()) + this.terminal.___dirty_all(c); + + return c; + } + + // TODO: DOESNT DO ON .SELF + debug = (c: DebugResult): DebugRay => { + if (c[this.label] !== undefined) + return c[this.label]!; + + const of = (ray: Ray): string => { + if (ray.as_reference().is_none()) return 'None'; + + ray.debug(c); + return ray.label; + } + + const obj: any = { label: this.label }; + c[this.label] = obj; + + obj.label = this.label; + obj.initial = of(this.initial); + obj.vertex = of(this.vertex); + obj.terminal = of(this.terminal); + obj.type = this.as_reference().type; + obj.is_initial = this.as_reference().is_initial(); + obj.is_vertex = this.as_reference().is_vertex(); + obj.is_terminal = this.as_reference().is_terminal(); + obj._dirty_store = this._dirty_store; + + return obj; + } + + /** + * TODO: This should be constructed at the vertex and in general unsolvable + */ + static _label: number = 0; + get label(): string { + if (this.any.label !== undefined) + return this.any.label; + + return this.any.label = `"${Ray._label++} (${this.any.debug?.toString() ?? '?'})})"`; + } + + push_back = (b: Ray) => this.last().compose(b); + push_front = (b: Ray) => this.first().compose(b); + + // [index: number]: Ray; + + // length: number; + // + // concat(...items: ConcatArray[]): Ray[]; + // concat(...items: (ConcatArray | Ray)[]): Ray[]; + // concat(...items: (ConcatArray | Ray)[]): Ray[] { + // return []; + // } + // + // copyWithin(target: number, start: number, end?: number): this { + // return undefined; + // } + // + // entries(): IterableIterator<[number, Ray]> { + // return undefined; + // } + // + // every(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): this is S[]; + // every(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean; + // every(predicate, thisArg?: any): any { + // } + // + // fill(value: Ray, start?: number, end?: number): this { + // return undefined; + // } + // + // filter(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S[]; + // filter(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray[]; + // filter(predicate, thisArg?: any): any { + // } + // + // find(predicate: (value: Ray, index: number, obj: Ray[]) => value is S, thisArg?: any): S | undefined; + // find(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // find(predicate, thisArg?: any): any { + // } + // + // findIndex(predicate: (value: Ray, index: number, obj: Ray[]) => unknown, thisArg?: any): number { + // return 0; + // } + // + // forEach(callbackfn: (value: Ray, index: number, array: Ray[]) => void, thisArg?: any): void { + // } + // + // indexOf(searchElement: Ray, fromIndex?: number): number { + // return 0; + // } + // + // join(separator?: string): string { + // return ""; + // } + // + // keys(): IterableIterator { + // return undefined; + // } + // + // lastIndexOf(searchElement: Ray, fromIndex?: number): number { + // return 0; + // } + // + // map(callbackfn: (value: Ray, index: number, array: Ray[]) => U, thisArg?: any): U[] { + // return []; + // } + // + // pop(): Ray | undefined { + // return undefined; + // } + // + // push(...items: Ray[]): number { + // return 0; + // } + // + // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; + // reduce(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; + // reduce(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduce(callbackfn, initialValue?): any { + // } + // + // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray): Ray; + // reduceRight(callbackfn: (previousValue: Ray, currentValue: Ray, currentIndex: number, array: Ray[]) => Ray, initialValue: Ray): Ray; + // reduceRight(callbackfn: (previousValue: U, currentValue: Ray, currentIndex: number, array: Ray[]) => U, initialValue: U): U; + // reduceRight(callbackfn, initialValue?): any { + // } + // + // reverse(): Ray[] { + // return []; + // } + // + // shift(): Ray | undefined { + // return undefined; + // } + // + // slice(start?: number, end?: number): Ray[] { + // return []; + // } + // + // some(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): boolean { + // return false; + // } + // + // sort(compareFn?: (a: Ray, b: Ray) => number): this { + // return undefined; + // } + // + // splice(start: number, deleteCount?: number): Ray[]; + // splice(start: number, deleteCount: number, ...items: Ray[]): Ray[]; + // splice(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // return []; + // } + // + // unshift(...items: Ray[]): number { + // return 0; + // } + // + // values(): IterableIterator { + // return undefined; + // } + // + // findLast(predicate: (value: Ray, index: number, array: Ray[]) => value is S, thisArg?: any): S | undefined; + // findLast(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): Ray | undefined; + // findLast(predicate, thisArg?: any): any { + // } + // + // findLastIndex(predicate: (value: Ray, index: number, array: Ray[]) => unknown, thisArg?: any): number { + // return 0; + // } + // + // flat(depth?: D): FlatArray[] { + // return []; + // } + // + // flatMap(callback: (this: This, value: Ray, index: number, array: Ray[]) => (ReadonlyArray | U), thisArg?: This): U[] { + // return []; + // } + // + // includes(searchElement: Ray, fromIndex?: number): boolean { + // return false; + // } + // + // toReversed(): Ray[] { + // return []; + // } + // + // toSorted(compareFn?: (a: Ray, b: Ray) => number): Ray[] { + // return []; + // } + // + // toSpliced(start: number, deleteCount: number, ...items: Ray[]): Ray[]; + // toSpliced(start: number, deleteCount?: number): Ray[]; + // toSpliced(start: number, deleteCount?: number, ...items: Ray[]): Ray[] { + // return []; + // } + // + // with(index: number, value: Ray): Ray[] { + // return []; + // } + + +} + +// default = (fn: () => any): any => self.match({ +// Some: (a) => a, +// None: () => fn() +// }) +// + + +/** + * + * Important to remember this is just one particular structure to which it can be mapped, there are probably many (TODO infinitely?) others. + * + * Not to be considered as a perfect mapping of JavaScript functionality - merely a practical one. + */ + + const Boolean = (boolean: boolean): Ray => { + // |-false->-true-| (could of course also be reversed) + const _false = Ray.vertex().o({ js: false }); + const _true = Ray.vertex().o({ js: true }); + _false.compose(_true); + + return (boolean ? _true : _false).as_reference(); + } + // const bit = (bit?: boolean): Arbitrary> => permutation(bit ? 1 : 0, 2); + const Bit = Boolean; + + const Iterable = (iterable: Iterable): Ray => Iterator(iterable[Symbol.iterator]()); + + const Iterator = (iterator: Iterator): Ray => { + // [ |--] + + const next = (initial: Ray): Ray => { + const iterator_result = iterator.next(); + const is_terminal = iterator_result.done === true; + + if (is_terminal) { + // We're done, this is the end of the iterator + + // vertex: could have something at the vertex which defines the "end of the iterator" - but we don't here. + const terminal = new Ray({ + initial: () => initial + }); + // initial.compose(() => terminal.as_reference()); + + // if (initial.is_some()) + // initial.terminal = () => terminal; // TODO REPEAT FROM BELOW + + return terminal; + } + + const current: Ray = new Ray({ + // initial: () => new Ray(), + initial: () => initial, + vertex: () => Any(iterator_result.value), + terminal: () => next(current) + }).o({js: iterator_result.value}); + + // initial.compose(() => current.as_reference()); + if (initial.is_some()) + initial.terminal = () => current; + + return current; + } + + const ray_iterator = Ray.None().o({ js: iterator }); + ray_iterator.terminal = () => next(ray_iterator); + + // This indicates we're passing a reference, since traversal logic will be defined at its vertex - what it's defining. + return ray_iterator.as_reference(); + } + + const Generator = (generator: Generator): Ray => Iterable(generator); + + // TODO Could have parallel threads in general. + // const AsyncGenerator = (generator: AsyncGenerator): Ray => { + // // [ |--] + // return JS.Iterable(generator); + // } + + const Number = (number: number): Ray => { + throw new NotImplementedError(); + } + + const Function = (func: Arbitrary): Ray => { + throw new NotImplementedError(); + } + + const Object = (object: object): Ray => Ray.vertex().o(object); + + const Any = (any: any): Ray => { + if (any === null || any === undefined) return Any(any); + if (is_boolean(any)) return Boolean(any); + if (is_number(any)) return Number(any); + if (is_iterable(any)) return Iterable(any); // || is_array(any)) + if (is_function(any)) return Function(any); + if (is_object(any)) return Object(any); + + // TODO + // return JS.Any(any); + return Ray.vertex().o({js: any}); + } + + const is_boolean = (_object: any): _object is boolean => _.isBoolean(_object); + const is_number = (_object: any): _object is number => _.isNumber(_object); + const is_object = (_object: any): _object is object => _.isObject(_object); + const is_iterable = (_object: any): _object is Iterable => Symbol.iterator in Object(_object); + const is_async_iterable = (_object: any): _object is AsyncIterable => Symbol.asyncIterator in Object(_object); + const is_array = (_object: any): _object is T[] => _.isArray(_object); + const is_async = (_object: any) => _.has(_object, 'then') && is_function(_.get(_object, 'then')); // TODO, Just an ugly check + + const is_error = (_object: any): _object is Error => _.isError(_object); + const is_function = (_object: any): _object is ((...args: any[]) => any) => _.isFunction(_object); + +class NotImplementedError extends Error {} +class PreventsImplementationBug extends Error {} + +/** + * Temporary Ray visualization till the visualization is incorporated into the editor (Basically when Visualization = Ray) + * + * TODO; Generalize to Ray - should be embedded on the vertex, or on another layer of description, where the interface is a rewrite rule + */ +type InterfaceOptions = { + position?: [number, number, number], + rotation?: [number, number, number], + scale?: number, + color?: string +} +type Options = { + initial?: InterfaceOptions, + vertex?: InterfaceOptions, + terminal?: InterfaceOptions, +} + +const torus = { + // Radius of the torus, from the center of the torus to the center of the tube. Default is 1. + radius: 3, color: "orange", segments: 200, tube: { width: 1, segments: 200 }, +} +const add = (a: number[], b: number[]): [number, number, number] => [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; + +const circle = { radius: 3, color: "orange", segments: 30, } From 775ed37e201a153617db9b89d4ce95d7037332fe Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Mon, 29 Jan 2024 20:47:49 +0100 Subject: [PATCH 134/138] 2024/01/29 - Boilerplate --- orbitmines.com/src/App.tsx | 4 + orbitmines.com/src/routes/Archive.tsx | 22 ++++ .../archive/2024.02.NGI.GrantProposal.tsx | 103 ++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 orbitmines.com/src/routes/Archive.tsx create mode 100644 orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx diff --git a/orbitmines.com/src/App.tsx b/orbitmines.com/src/App.tsx index f8a1f3a..e1fc51b 100755 --- a/orbitmines.com/src/App.tsx +++ b/orbitmines.com/src/App.tsx @@ -12,6 +12,7 @@ import BlueprintJS from "./lib/layout/experimental-designs/BlueprintJS"; import Modules from "./@orbitmines/js/react/Modules"; import Icons from "./lib/layout/experimental-designs/Icons"; import {ThumbnailPage} from "./lib/paper/Paper"; +import Archive from "./routes/Archive"; export const Router = () => { @@ -23,6 +24,9 @@ export const Router = () => { } /> + + } /> + } /> {/* TODO */} {/**/} diff --git a/orbitmines.com/src/routes/Archive.tsx b/orbitmines.com/src/routes/Archive.tsx new file mode 100644 index 0000000..5ecc350 --- /dev/null +++ b/orbitmines.com/src/routes/Archive.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import {useParams} from "react-router-dom"; +import Error from "./Error"; +import _2024_02_NGI_GrantProposal from "./archive/2024.02.NGI.GrantProposal"; + +const ITEMS: { [key: string]: any } = { + '2024-02-ngi-grant-proposal': _2024_02_NGI_GrantProposal, +} + +const Archive = () => { + const params = useParams(); + const { item } = params; + + const Element = item ? ITEMS[item] : undefined; + + if (!Element) + return + + return +}; + +export default Archive; \ No newline at end of file diff --git a/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx b/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx new file mode 100644 index 0000000..c48eeee --- /dev/null +++ b/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx @@ -0,0 +1,103 @@ +import React from 'react'; +import JetBrainsMono from "../../lib/layout/font/fonts/JetBrainsMono/JetBrainsMono"; +import ORGANIZATIONS, {Content, Viewed} from "../../lib/organizations/ORGANIZATIONS"; +import {useNavigate} from "react-router-dom"; +import Paper, {PaperProps} from "../../lib/paper/Paper"; +import Reference, {useCounter} from "../../lib/paper/layout/Reference"; +import {PROFILES} from "../../profiles/profiles"; +import {renderable} from "../../lib/typescript/React"; +import Section from '../../lib/paper/layout/Section'; +import Arc from '../../lib/paper/layout/Arc'; +import BR from "../../lib/paper/layout/BR"; +import {Row} from "../../lib/layout/flexbox"; +import Link from "../../lib/paper/layout/Link"; + +export const _2024_02_NGI_GRANT_PROPOSAL: Content = { + reference: { + title: "NGI Grant Proposal: (Hypergraphic) Version Control System through Rays", + subtitle: "", + draft: true, + link: 'https://orbitmines.com/archive/2024-02-ngi-grant-proposal', + year: "2024", + date: "2024-01-30", + external: { + }, + organizations: [ORGANIZATIONS.orbitmines_research], + authors: [{ + ...PROFILES.fadi_shawki, + external: PROFILES.fadi_shawki.external?.filter((profile) => [ + ORGANIZATIONS.github.key, + ORGANIZATIONS.twitter.key, + ORGANIZATIONS.discord.key, + ORGANIZATIONS.orcid.key, + ].includes(profile.organization.key)) + }], + }, status: Viewed.VIEWED, found_at: "2024", viewed_at: "January, 2024" +} + +const _2024_02_NGI_GrantProposal = () => { + const navigate = useNavigate(); + + const referenceCounter = useCounter(); + + const paper: Omit = { + ..._2024_02_NGI_GRANT_PROPOSAL.reference, + subtitle: renderable("", (value: any) => <> + A grant proposal to through + ), + pdf: { + fonts: [JetBrainsMono], + }, + Reference: (props: {}) => (<>), + references: referenceCounter + } + + return + + +
+ Open Call +
+
+ +
+
+
+
+
+
+ +
+
}>
+
+ + +
+
+ +
+
+ + +
+ 50.000 € +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+} + +export default _2024_02_NGI_GrantProposal; \ No newline at end of file From 24b8e9d0721d6cb740f9ab3e2496a7b8cb561494 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 31 Jan 2024 13:42:25 +0100 Subject: [PATCH 135/138] 2024/01/31 - License changes --- README.md | 28 +- .../javascript/@orbitmines/rays/src/Ray.ts | 1211 +++++++++-------- .../archive/2024.02.NGI.GrantProposal.tsx | 26 +- 3 files changed, 643 insertions(+), 622 deletions(-) diff --git a/README.md b/README.md index 7f70521..3dc044d 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Most importantly, it is here as infrastructure. Infrastructure for the design an ## Where is OrbitMines going with this? - i.e. Future inquiries - +Check out everything I've made public regarding this here: https://github.com/orbitmines/orbitmines.com/issues or equivalently, check the Discord channels grouped under the name: [Fractals of the Galaxy](https://discord.com/channels/1055502602365845534/1114584997702156388). --- @@ -72,6 +72,8 @@ Most importantly, it is here as infrastructure. Infrastructure for the design an ## JavaScript Interface Examples +**This is just preliminary, I'll change this later** + > [!WARNING] > Reasoning backwards, what should the JavaScript interface look like? @@ -92,29 +94,11 @@ const terminal = Ray.boolean().orbit().size(2); ``` +--- +## License Magic - - - - - - - - - - - - - - - - - - - - - +I'm not convinced putting licenses on the repo's in the usual case is anything other than *Minecraft servers putting "Not affiliated with Mojang" in their stores* just because everyone else does it. But here: after doing absolutely no research into the international ramifications: [LICENSE](./LICENSE) a license for those who like to look at them. Try to reason to what that applies in this repository, obviously that doesn't cover everything not made by me or other contributions to OrbitMines or something. diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index 58b1377..63dcad3 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -1,596 +1,615 @@ -import JS, {NotImplementedError} from "@orbitmines/js"; - -namespace Ray { - - export type Any = - { - /** Ray is a function (.next) */ - (...other: JS.Recursive): Ray.Any, - - /** Ray is a constructor - TODO: Copy? */ - new (...other: JS.Recursive): Ray.Any, - } - /** JavaScript runtime conversions. */ - & Symbol - & Iterable - & AsyncIterable - - & Pick - - /** Preconfigured functions defined for Rays. */ - & { - -readonly [TKey in keyof typeof Ray.Function.All]: typeof Ray.Function.All[TKey] extends Ray.Any - ? Ray.Any - : never; - } - - /** Storage/Movement operations which need to be implemented. */ - & { [TKey in keyof Ray.Op.Impl]: Ray.Any } - - export namespace Debug { - export type Event = { event: string, self: Ray.Any, context: any }; - export type Listener = (event: Event) => void; - } - - /** - * An uninitialized empty Ray, which caches itself once initialized. - */ - // export const None: Ray.FunctionConstructor = Ray.Function.CachedAfterUse(Ray.New); - - // export class Object { - // - // // TODO: Could copy? - // get initial(): Ray.Any { return this._initial(); } set initial(initial: Ray.Any) { this._initial = initial; } protected _initial: Ray.Any; - // get self(): Ray.Any { return this._self(); } set self(self: Ray.Any) { this._self = self; } protected _self: Ray.Any; - // get terminal(): Ray.Any { return this._terminal(); } set terminal(terminal: Ray.Any) { this._terminal = terminal; } protected _terminal: Ray.Any; - // - // protected constructor({ initial, self, terminal }: { initial?: Ray.Any, self?: Ray.Any, terminal?: Ray.Any } = {}) { - // - // this._initial = initial ?? Ray.none.memoized; - // this._self = self ?? Ray.self_reference; - // this._terminal = terminal ?? Ray.none.memoized; - // } - // } - - /** A simplistic compiler for Ray */ - export namespace Compiler { // TODO Ray is Compiler - - /** - * TODO: Compiler could have things like other composed rays which tell it cares about the other (even if that's correct or not??) - * - * - * TODO: Do I want to keep the is_equiv/is_composed pattern? Or simplify to one of the two? - * - * // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY - * - * TODO - * - Compose empty as first element? Disregard none to first elemn? Or not?? - * - * TODO; Impl - * - Generally, return something which knows where all continuations are. - * - Generator/step function/... ; with no assumption of halting, but allow to hook into any step. - * - Cache: - * - Control of (non-/)lazyness of functions - * - None as, first time called, memoize func. - * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence - * - a.orbit() -> a.orbit(a) - * // TODO: Should be automatic? is_orbit() or any method without arguments is a.is_orbit(a.self()) ?? not a.is_orbit(a) ; ??? - * - * - .initial/.terminal can be seen as a particular connection on .self, which .self ignores? - * - * TODO: Allow hooking - * - * TODO: Testing - * - Test if references hold after equivalence/composition... - * - * TODO: After initial demo: - * - Allow mapping/finding of other implementations regarding some equiv funcs (like different ways of implementing using NAND etc...) - * - * Arbitrary. - */ - } - - export type Constructor = { proxy?: ProxyHandler, debug?: Debug.Listener, } - - export class Instance extends JS.Class.Instance { - - listeners: Debug.Listener[]; - - constructor({ - proxy, - debug, - }: Ray.Constructor = {}) { - super({ proxy: proxy ?? Ray.ProxyHandlers.Default }); - - this.listeners = debug ? [debug] : []; - } - - /** Used to jump out of the proxy. */ - get ___instance(): Instance { return this; } - - debug = ( - on: Debug.Listener, - func: JS.ParameterlessFunction - ): T => { - this.listeners.push(on); - const ret = func(); - this.listeners.pop(); // TODO? - - return ret; - } - - /** Simple debug/traversal mechanism. */ - on = (event: Omit) => { - if (!this.listeners) return; - - this.listeners.forEach(listener => listener({ ...event, self: this.proxy })); - } - - } - - - export namespace ProxyHandlers { - - export const Default: ProxyHandler = JS.Class.Handler({ - /** ray.property */ - get: (self: Ray.Any, instance: Ray.Instance, property: string | symbol): any => { - instance.on({ event: 'PROXY.GET', context: { property } }); - - /** Use any field on {Ray.Instance}, which we want to delegate to, first. */ - if (property === '___instance' || property === 'debug' || property === 'on') { return instance[property]; } - - /** Otherwise, switch to functions defined on {Ray.Functions} */ - const func = Ray.Function.Get(property as any); - if (func) { return func.as_method({ self, property }); } - - if (property === Symbol.toPrimitive) - return (hint: string) => { return 100; }; // TODO: Can be used to setup label generation through javascript objects if we want to ? + allow search on this - // throw new NotImplementedError(``); - - /** Not implemented. */ - throw new NotImplementedError(`Called property '${String(property)}' on Ray, which has not been implemented.`); - }, - - /** ray.property = something; */ - set: (self: Ray.Any, instance: Ray.Instance, property: string | symbol, value: any): boolean => { - instance.on({ event: 'PROXY.SET', context: { property, value } }); - - throw new NotImplementedError(); - }, - - /** delete ray.property; */ - deleteProperty: (self: Ray.Any, instance: Ray.Instance, property: string | symbol): boolean => { - instance.on({ event: 'PROXY.DELETE', context: { property } }); - - throw new NotImplementedError(); - }, - - /** ray() is called. */ - apply: (self: Ray.Any, instance: Ray.Instance, args: any[]): any => { - instance.on({ event: 'PROXY.APPLY', context: { args } }); - - throw new NotImplementedError(`${self}`); - }, - - /** new ray() */ - construct: (self: Ray.Any, instance: Ray.Instance, args: any[]): object => { - instance.on({ event: 'PROXY.NEW', context: { args } }); - - throw new NotImplementedError(`${args.length} ${self}`); - }, - - /** property in ray; */ - has: (self: Ray.Any, instance: Ray.Instance, property: string | symbol): boolean => { - instance.on({ event: 'PROXY.HAS', context: { property } }); - - throw new NotImplementedError(`${String(property)}`); - }, - }); - } - - /** Ray is an Enum(eration) */ - export namespace Enum { - - export type Type> = { - [TKey in T[number]]: Ray.Any - } - - export const Impl = >(...enumeration: T): Type => { - return Object.fromEntries(enumeration.map(value => - [value, Ray.Function.None.Impl((): Ray.Any => { - throw new NotImplementedError(); // TODO - })] - )) as Type; - // TODO: ONE OF 4 SELECTION RAY for the case of type. - } - - } - - /** Ray is a function (.next) */ - export namespace Function { - - /** {T} is just an example/desired use case. But it generalizes to any function. */ - export type Type = T | Ray.Any; - - /** From which perspective the Function is implemented. */ - enum Perspective { - None, Self, /** Ref, */ - } - - // /** - // * Implement a function from the perspective of 'this' for 'this.self'. - // */ - // // static Ref = (impl: (ref: Ray.Any) => TResult): Function => Ray.Function.Self(self => impl(self.as_reference())); - - /** Implement a function from no (or: an ignorant) perspective. */ - export namespace None { - - export const Impl = (impl: Op.Zeroary.Type): Ray.Any => { - throw new NotImplementedError(); - // return new Ray.Any({ perspective: Perspective.None, impl }); - } - - } - - /** Implement a function from the perspective of 'this' */ - export namespace Self { - export const Impl = (impl: Op.Unary.Type): Ray.Any => { - throw new NotImplementedError(); - // return new Ray.Any({ perspective: Perspective.Self, impl }); - } - - export const Binary = (impl: Op.Binary.Type): Ray.Any => { - throw new NotImplementedError(); - // return new Ray.Any({ perspective: Perspective.Self, impl }); // TODO: Good way to deal with arity - } - - // export const If = (impl: Op.Unary.Type): Ray.Any => { - // return Impl(impl); // TODO: GENERIC collapse to boolean implemented and overridable - // } - // TODO: GENERIC collapse to boolean implemented and overridable - - /** - * TODO: - * - Maybe replace switch with 'zip'?, What are the practical differences? - */ - // export const Match = (cases: MatchCases): Ray.Any => { - // return Impl(self => self); // TODO - // } - } - } - - export namespace Op { - - export type Impl = - { [TKey in keyof (typeof Op.Zeroary.All)]: Op.Zeroary.Type } - & { [TKey in keyof (typeof Op.Unary.All)]: Op.Unary.Type } - & { [TKey in keyof (typeof Op.Binary.All)]: Op.Binary.Type } - - export const all = (ops: TOps): { - [TOP in keyof TOps]: Ray.Any - } => ({}); - - export namespace Zeroary { - export type Type = () => T; - export type Any = (keyof typeof Op.Zeroary.All) | Type; - - // TODO: set = none; - // TODO: Destroy the current thing, connect .initial & .terminal ? (can do just direct connection, preserves 'could have been something here') - then something like [self.initial, self, self.terminal].pop(). - // TODO: Leave behind --] [-- or connect them basically.. - export const All = Op.all({ - // @alias('alloc', 'new', 'create', 'initialize') - none: 'none', - }); - } - export namespace Unary { - export type Type = (a: T) => T; - export type Any = (keyof typeof Op.Unary.All) | Type; - - export const All = Op.all({ - - // @alias('free', 'destroy', 'clear', 'delete', 'pop') - free: 'free', - - /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ - initial: 'initial', // a.initial - - /** - * An arbitrary Ray, defining what our current position is equivalent to. - * - * Moving to the intersecting Ray at `.self` - as a way of going an abstraction layer (lower), and asking what's inside. - */ - // @alias('dereference', 'self') - self: 'self', // a.self - - /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ - terminal: 'terminal', // a.terminal - }); - } - export namespace Binary { - export type Type = (a: T, b: T) => T; - export type Any = (keyof typeof Op.Binary.All) | Type; - - export const All = Op.all({ - initial: 'initial', // a.initial = b - self: 'self', // a.self = b - terminal: 'terminal', // a.terminal = b - - /** - * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. - * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. - */ - // @alias('is_none') - is_orbit: 'is_orbit', // a.___instance === b.___instance - }); - } - } - - export namespace Function { - export const Get = ( - property: TProperty - ): (typeof Ray.Function.All)[TProperty] | undefined => Ray.Function.All[property as TProperty] ?? undefined; - - export namespace All { - - /** [ |-?] */ export const is_initial = Ray.Function.Self.Impl( - self => self.initial().is_none() - ); - /** [--|--] */ export const is_vertex = Ray.Function.Self.Impl( - self => self.is_initial().nor(self.is_terminal()) - ); - /** [?-| ] */ export const is_terminal = Ray.Function.Self.Impl( - self => self.terminal().is_none() - ); - /** [ | ] */ export const is_reference = Ray.Function.Self.Impl( - self => self.is_initial().and(self.is_terminal()) - ); - /** [?-| ] or [ |-?] */ export const is_boundary = Ray.Function.Self.Impl( - self => self.is_initial().xor(self.is_terminal()) - ); - - /** - * This is basically what breaks the recursive structure. - * - * Tries for "global coherence", practically this just means self-reference, were no change is (inconsistently) assumed... - * - * --- - * - * Another way of interpreting a possible way of implementing it, is no matter how much more detail we would like to ask, the only thing we ever see is the same structure again (if we ignore the difference of us asking about that additional structure, that's still a possible handle on some difference). - * - * As a way of saying/.../assuming: I only 'infinitely' assume it's only this structure, "it seems to halt here". Note that this is necessarily an assumption. No guarantee of this can be made. This is necessarily an equivalence, ..., ignorance. - * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. - */ - export const is_none = Ray.Op.Binary.All.is_orbit; - export const is_some = Ray.Function.Self.Impl( - self => self.is_none().not() - ); - - /** - * @see "Continuations as Equivalence (can often be done in parallel - not generally)": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence - */ - // @alias('merge, 'continues_with', 'compose') - export const compose = Ray.Function.Self.Binary( - (a, b) => a.terminal().equivalent(b.initial()) - ); - - /** - * "Composing an terminal & initial boundary" - * - TODO: Note that an orbit is reversibility. ? - * - TODO: Could represent this abstraction in another layer what we want to accomplish while the actual search is still taking place. - * - * - Like with 'copy' and all concepts: Note that we're only after reversibility after ignoring some difference. - * - * @see "Reversibility is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Another%20example%20of%20this%20is%20reversibility - */ - // @alias('modular', 'modulus', 'orbit', 'circle', 'repeats', 'infinitely') - export const orbit = Ray.Function.Self.Binary( - /** - * - TODO: If we're only doing one end: This already assumes they are connected on the other end. - * - TODO: should be a connection here, with is_composed ; or "reference.is_equivalent" so that you can drop one of the sides, or both. - */ - (a, b) => { - b.last().compose(a.first()); - a.first().compose(b.last()); - - return a; // ? - } - ); - - /** - * Equivalence as "Composition of Ray." - * - * NOTE: - * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. And it is expensive work to edge towards global coherence. - * - Though changes are only applied locally, their effects can be global (Take for instance, the example of adding to one Ray, which changes the perspective of everything connected to that Ray if they were to traverse the connection). - * - * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies - */ - export const equivalent = Ray.Function.Self.Binary( - (a, b) => { - // throw new NotImplementedError(); - - // TODO: This is close but not quite, use the shifting thing I wrote down a few days ago: (And then use something to break the self-reference) - Either on this side. compose, or outside the definitions - // This one harder to do in parallel? - return a.self().compose(b.self()); - }); - - /** - * If there exists an orbit between A & B anywhere on their equivalency functions - or: their .self - (except for the directions through which we're referencing them) - * - * Note the connection between 'is_orbit' vs 'is_equivalence'. They're essentially the same thing, but: - * - in the case of 'is_equivalence' we directly have access to their difference but are explicitly ignoring them - in the context in which this functionality is called. - * - in the case of 'is_orbit', we might need to do more complicated things to acknowledge their differences - we don't have direct access to them. - * - * TODO: (so dually connected, what if only one is aware??) Or basically just ; the answer in this particular instance is just if either end can find the other only once. Consistency of it defined on a more abstract level... - */ - // @alias('includes', 'contains') ; (slightly different variants?) - export const is_equivalent = Ray.Function.Self.Binary( - (a, b) => a.self().traverse().is_orbit(b.self().traverse()) - ); - // TODO: Either is_equiv or is_composed will likely change?. - export const is_composed = Ray.Function.Self.Binary( - (a, b) => a.traverse().is_orbit(b.traverse()) // Basically: does there exist a single connection between the two? - ); - - export const traverse = Ray.Function.Self.Impl( - (a) => { throw new NotImplementedError(); } - ); - - // TODO: .terminal/.initial is self() vs self.not() - export const next = Ray.Function.Self.Impl((self) => { - throw new NotImplementedError(); - return self; - }); - export const has_next = Ray.Function.Self.Impl((self) => self.next().is_some()); - // @alias('end', 'result', 'back', 'output') - export const last = Ray.Function.Self.Impl((self) => { - throw new NotImplementedError(); - return self; - }); - - export const previous = Ray.Function.Self.Impl((self) => self.not().next()); - // @alias() - export const has_previous = Ray.Function.Self.Impl((self) => self.not().has_next()); - // @alias('beginning', 'front') - export const first = Ray.Function.Self.Impl((self) => self.not().last()); - - // @alias('not', 'reverse', 'swap', 'converse', 'negative', 'neg') - // export const not = Ray.Function.Self.Impl(self => ); - // self.terminal = self.initial(); - // self.initial = self.terminal(); - // self.not().not() = self - // TODO: What's the difference in context between stepping after not / or not doing so. - // TODO; OR BINARY? - "It's just always .next from some perspective?" - // TODO: Level at which "not" is applied. - export const not = Ray.Function.Self.Binary((a, b) => b); - - export const and = Ray.Function.Self.Binary((a, b) => { throw new NotImplementedError(); - } ); - export const or = Ray.Function.Self.Binary((a, b) => { - throw new NotImplementedError(); - return self; - }); - export const xor = Ray.Function.Self.Binary((a, b) => a.xnor(b).not()); - export const xnor = Ray.Function.Self.Binary((a, b) => a.is_orbit(b)); // TODO: Could be 'is_equivalent' too? - export const nand = Ray.Function.Self.Binary((a, b) => a.and(b).not()); - export const nor = Ray.Function.Self.Binary((a, b) => a.or(b).not()); - - - // @alias(`push_{last.alias}`) - export const push_back = Ray.Function.Self.Binary( - (a, b) => a.last().compose(b) - ); - // @alias(`push_{first.alias}`) - export const push_front = Ray.Function.Self.Binary( - (a, b) => b.compose(a.first()) - ); - - /** - * Performing a copy (realizing it) can be conceptualized as traversing the entire structure. (Where the 'entire structure' means the current instantiation of it - with many ignorances attached) - * - * - A problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. - * - This copy does not do that. Instead, it is ignorant of other things referencing the thing it's copying. - * - Additionally, a copy necessarily has some non-redundancy to it: - * - * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy - */ - // @alias('clone', 'duplicate') - export const copy = Ray.Function.Self.Impl( - // or - // (self) => self.self.copy.reference() - (self) => none().self = self.self.copy() - - // TODO Relies heavily on the execution layer to copy initial/terminal etc... ; and an is_orbit check before calling copy again. - Then again on the execution layer it can lazily do this copy (by not evaluating (i.e.) traversing everywhere), or it first does this traversing directly. - ); - - /** - * Placing existing structure on a new Reference, Boundary or Vertex: - */ - // TODO: These should allow as_vertex as zero-ary, but that means self = self_reference, not none. ? - /** - * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. - * - * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) - */ - export const as_reference = Ray.Function.Self.Impl( - self => none().self = self - ); - - // TODO as_reference.as_vertex instead of as_vertex ignorant by default? - - export const as_vertex = Ray.Function.Self.Impl((self) => { - const vertex = Ray.Op.Zeroary.All.none(); - vertex.initial = self_reference; - vertex.terminal = self_reference; - vertex.self = self; // TODO: Like this, ignorant vs non-ignorant? What to do here? - - return vertex; - }); - export const as_terminal = Ray.Function.Self.Impl((self) => { - const terminal = Ray.Op.Zeroary.All.none(); - terminal.initial = self_reference; - // terminal.terminal = none; - terminal.self = self; - - return terminal; - }); - export const as_initial = Ray.Function.Self.Impl((self) => { - const initial = Ray.Op.Zeroary.All.none(); - // initial.initial = none; - initial.terminal = self_reference; - initial.self = self; - - return initial; - }); - - /** - * Any arbitrary direction, where .not (or reversing the direction) relies on some memory mechanism - */ - export const memoized = Ray.Function.Self.Impl( - self => { throw new NotImplementedError(); } - ); - } - } - - /** JavaScript runtime conversions */ - export const array = (array: T[]): Ray.Any => Ray.iterable(array); - export const iterable = (iterable: Iterable): Ray.Any => Ray.iterator(iterable[Symbol.iterator]()); - export const async_iterable = (async_iterable: AsyncIterable): Ray.Any => Ray.async_iterator(async_iterable[Symbol.asyncIterator]()); - export const iterator = (iterator: Iterator): Ray.Any => { throw new NotImplementedError(); } - export const async_iterator = (async_iterator: AsyncIterator): Ray.Any => { throw new NotImplementedError(); } - export const generator = (generator: Generator): Ray.Any => Ray.iterator(generator); - export const async_generator = (generator: AsyncGenerator): Ray.Any => Ray.async_iterator(generator); - - export const number = (number: number) => { throw new NotImplementedError(); } - - export const self_reference = Ray.Function.Self.Impl( - self => self - ); - export const none = Ray.Op.Zeroary.All.none; // TODO FOR ALL OPS, ? automatic, or just put them here. - - // export const Boundary = { INITIAL: Type.INITIAL, TERMINAL: Type.TERMINAL }; TODO: LIST O - - // TODO CAN ALSO BE ZERO-ARY.. - // @alias('resize', 'size', 'structure', 'length', 'duplicate', 'copy') -> Should be generalized as any kind of structure, but with this thing repeated on it. ; use traversal or ... - export const size = Ray.Function.Self.Binary( - (a, size) => { throw new NotImplementedError(); } - ); - // @alias('bit') - export const boolean = size(2); - - export const vertex = Ray.Function.Self.Impl( - (self) => { throw new NotImplementedError(); } - ); - export const initial = Ray.Function.Self.Impl( - (self) => { throw new NotImplementedError(); } - ); - export const terminal = Ray.Function.Self.Impl( - (self) => { throw new NotImplementedError(); } - ); -} - -export default Ray; \ No newline at end of file +// import JS, {NotImplementedError} from "@orbitmines/js"; +// +// namespace Ray { +// +// export type Any = +// { +// /** Ray is a function (.next) */ +// (...other: JS.Recursive): Ray.Any, +// +// /** Ray is a constructor - TODO: Copy? */ +// new (...other: JS.Recursive): Ray.Any, +// } +// /** JavaScript runtime conversions. */ +// & Symbol +// & Iterable +// & AsyncIterable +// +// & Pick +// +// /** Preconfigured functions defined for Rays. */ +// & { +// -readonly [TKey in keyof typeof Ray.Function.All]: typeof Ray.Function.All[TKey] extends Ray.Any +// ? Ray.Any +// : never; +// } +// +// /** Storage/Movement operations which need to be implemented. */ +// & { [TKey in keyof Ray.Op.Impl]: Ray.Any } +// +// export namespace Debug { +// export type Event = { event: string, self: Ray.Any, context: any }; +// export type Listener = (event: Event) => void; +// } +// +// /** +// * An uninitialized empty Ray, which caches itself once initialized. +// */ +// // export const None: Ray.FunctionConstructor = Ray.Function.CachedAfterUse(Ray.New); +// +// // export class Object { +// // +// // // TODO: Could copy? +// // get initial(): Ray.Any { return this._initial(); } set initial(initial: Ray.Any) { this._initial = initial; } protected _initial: Ray.Any; +// // get self(): Ray.Any { return this._self(); } set self(self: Ray.Any) { this._self = self; } protected _self: Ray.Any; +// // get terminal(): Ray.Any { return this._terminal(); } set terminal(terminal: Ray.Any) { this._terminal = terminal; } protected _terminal: Ray.Any; +// // +// // protected constructor({ initial, self, terminal }: { initial?: Ray.Any, self?: Ray.Any, terminal?: Ray.Any } = {}) { +// // +// // this._initial = initial ?? Ray.none.memoized; +// // this._self = self ?? Ray.self_reference; +// // this._terminal = terminal ?? Ray.none.memoized; +// // } +// // } +// +// /** A simplistic compiler for Ray */ +// export namespace Compiler { // TODO Ray is Compiler +// +// /** +// * In the case of Rays, whether something is a vertex/initial/terminal is only inferred from surrounding context. And these checks only need to happen locally in order to decide how to traverse arbitrary structure (as in - I only need to check the presence of something next to me, not traverse the whole direction recursively in order to decide what to do). +// * +// * How about treating something like something which the context says it's not? (Could apply this sort of thing in some fidelity/consistency checking mechanism as a way of fuzzing the fidelity mechanism) +// * +// * TODO: Compiler could have things like other composed rays which tell it cares about the other (even if that's correct or not??) +// * +// * +// * TODO: Do I want to keep the is_equiv/is_composed pattern? Or simplify to one of the two? +// * +// * // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY +// * +// * TODO +// * - Compose empty as first element? Disregard none to first elemn? Or not?? +// * +// * TODO; Impl +// * - Generally, return something which knows where all continuations are. +// * - Generator/step function/... ; with no assumption of halting, but allow to hook into any step. +// * - Cache: +// * - Control of (non-/)lazyness of functions +// * - None as, first time called, memoize func. +// * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence +// * - a.orbit() -> a.orbit(a) +// * // TODO: Should be automatic? is_orbit() or any method without arguments is a.is_orbit(a.self()) ?? not a.is_orbit(a) ; ??? +// * +// * - .initial/.terminal can be seen as a particular connection on .self, which .self ignores? +// * +// * TODO: Allow hooking +// * +// * TODO: Testing +// * - Test if references hold after equivalence/composition... +// * +// * TODO: After initial demo: +// * - Allow mapping/finding of other implementations regarding some equiv funcs (like different ways of implementing using NAND etc...) +// * +// * Arbitrary. +// * +// * TODO Pass a single ray to the runtime, and run that way? Access runtime as variable from ray? That would have programs accessing possible runtimes? +// */ +// } +// +// export type Constructor = { proxy?: ProxyHandler, debug?: Debug.Listener, } +// +// export class Instance extends JS.Class.Instance { +// +// listeners: Debug.Listener[]; +// +// constructor({ +// proxy, +// debug, +// }: Ray.Constructor = {}) { +// super({ proxy: proxy ?? Ray.ProxyHandlers.Default }); +// +// this.listeners = debug ? [debug] : []; +// } +// +// /** Used to jump out of the proxy. */ +// get ___instance(): Instance { return this; } +// +// debug = ( +// on: Debug.Listener, +// func: JS.ParameterlessFunction +// ): T => { +// this.listeners.push(on); +// const ret = func(); +// this.listeners.pop(); // TODO? +// +// return ret; +// } +// +// /** Simple debug/traversal mechanism. */ +// on = (event: Omit) => { +// if (!this.listeners) return; +// +// this.listeners.forEach(listener => listener({ ...event, self: this.proxy })); +// } +// +// } +// +// +// export namespace ProxyHandlers { +// +// export const Default: ProxyHandler = JS.Class.Handler({ +// /** ray.property */ +// get: (self: Ray.Any, instance: Ray.Instance, property: string | symbol): any => { +// instance.on({ event: 'PROXY.GET', context: { property } }); +// +// /** Use any field on {Ray.Instance}, which we want to delegate to, first. */ +// if (property === '___instance' || property === 'debug' || property === 'on') { return instance[property]; } +// +// /** Otherwise, switch to functions defined on {Ray.Functions} */ +// const func = Ray.Function.Get(property as any); +// if (func) { return func.as_method({ self, property }); } +// +// if (property === Symbol.toPrimitive) +// return (hint: string) => { return 100; }; // TODO: Can be used to setup label generation through javascript objects if we want to ? + allow search on this +// // throw new NotImplementedError(``); +// +// /** Not implemented. */ +// throw new NotImplementedError(`Called property '${String(property)}' on Ray, which has not been implemented.`); +// }, +// +// /** ray.property = something; */ +// set: (self: Ray.Any, instance: Ray.Instance, property: string | symbol, value: any): boolean => { +// instance.on({ event: 'PROXY.SET', context: { property, value } }); +// +// throw new NotImplementedError(); +// }, +// +// /** delete ray.property; */ +// deleteProperty: (self: Ray.Any, instance: Ray.Instance, property: string | symbol): boolean => { +// instance.on({ event: 'PROXY.DELETE', context: { property } }); +// +// throw new NotImplementedError(); +// }, +// +// /** ray() is called. */ +// apply: (self: Ray.Any, instance: Ray.Instance, args: any[]): any => { +// instance.on({ event: 'PROXY.APPLY', context: { args } }); +// +// throw new NotImplementedError(`${self}`); +// }, +// +// /** new ray() */ +// construct: (self: Ray.Any, instance: Ray.Instance, args: any[]): object => { +// instance.on({ event: 'PROXY.NEW', context: { args } }); +// +// throw new NotImplementedError(`${args.length} ${self}`); +// }, +// +// /** property in ray; */ +// has: (self: Ray.Any, instance: Ray.Instance, property: string | symbol): boolean => { +// instance.on({ event: 'PROXY.HAS', context: { property } }); +// +// throw new NotImplementedError(`${String(property)}`); +// }, +// }); +// } +// +// /** Ray is an Enum(eration) */ +// export namespace Enum { +// +// export type Type> = { +// [TKey in T[number]]: Ray.Any +// } +// +// export const Impl = >(...enumeration: T): Type => { +// return Object.fromEntries(enumeration.map(value => +// [value, Ray.Function.None.Impl((): Ray.Any => { +// throw new NotImplementedError(); // TODO +// })] +// )) as Type; +// // TODO: ONE OF 4 SELECTION RAY for the case of type. +// } +// +// } +// +// /** Ray is a function (.next) */ +// export namespace Function { +// +// /** {T} is just an example/desired use case. But it generalizes to any function. */ +// export type Type = T | Ray.Any; +// +// /** From which perspective the Function is implemented. */ +// enum Perspective { +// None, Self, /** Ref, */ +// } +// +// // /** +// // * Implement a function from the perspective of 'this' for 'this.self'. +// // */ +// // // static Ref = (impl: (ref: Ray.Any) => TResult): Function => Ray.Function.Self(self => impl(self.as_reference())); +// +// /** Implement a function from no (or: an ignorant) perspective. */ +// export namespace None { +// +// export const Impl = (impl: Op.Zeroary.Type): Ray.Any => { +// throw new NotImplementedError(); +// // return new Ray.Any({ perspective: Perspective.None, impl }); +// } +// +// } +// +// /** Implement a function from the perspective of 'this' */ +// export namespace Self { +// export const Impl = (impl: Op.Unary.Type): Ray.Any => { +// throw new NotImplementedError(); +// // return new Ray.Any({ perspective: Perspective.Self, impl }); +// } +// +// export const Binary = (impl: Op.Binary.Type): Ray.Any => { +// throw new NotImplementedError(); +// // return new Ray.Any({ perspective: Perspective.Self, impl }); // TODO: Good way to deal with arity +// } +// +// // export const If = (impl: Op.Unary.Type): Ray.Any => { +// // return Impl(impl); // TODO: GENERIC collapse to boolean implemented and overridable +// // } +// // TODO: GENERIC collapse to boolean implemented and overridable +// +// /** +// * TODO: +// * - Maybe replace switch with 'zip'?, What are the practical differences? +// */ +// // export const Match = (cases: MatchCases): Ray.Any => { +// // return Impl(self => self); // TODO +// // } +// } +// } +// +// export namespace Op { +// +// /** +// * TODO: readonly setup, where only traversal ops are allowed. Of course these are writing in some sense, bit those writings aren't directly accessible from this perspective +// * +// */ +// +// export type Impl = +// { [TKey in keyof (typeof Op.Zeroary.All)]: Op.Zeroary.Type } +// & { [TKey in keyof (typeof Op.Unary.All)]: Op.Unary.Type } +// & { [TKey in keyof (typeof Op.Binary.All)]: Op.Binary.Type } +// +// export const all = (ops: TOps): { +// [TOP in keyof TOps]: Ray.Any +// } => ({}); +// +// export namespace Zeroary { +// export type Type = () => T; +// export type Any = (keyof typeof Op.Zeroary.All) | Type; +// +// // TODO: set = none; +// // TODO: Destroy the current thing, connect .initial & .terminal ? (can do just direct connection, preserves 'could have been something here') - then something like [self.initial, self, self.terminal].pop(). +// // TODO: Leave behind --] [-- or connect them basically.. +// export const All = Op.all({ +// // @alias('alloc', 'new', 'create', 'initialize') +// none: 'none', +// }); +// } +// export namespace Unary { +// export type Type = (a: T) => T; +// export type Any = (keyof typeof Op.Unary.All) | Type; +// +// export const All = Op.all({ +// +// // @alias('free', 'destroy', 'clear', 'delete', 'pop') +// free: 'free', +// +// /** An arbitrary Ray, defining what continuing in the reverse of this direction is equivalent to. */ +// initial: 'initial', // a.initial +// +// /** +// * An arbitrary Ray, defining what our current position is equivalent to. +// * +// * Moving to the intersecting Ray at `.self` - as a way of going an abstraction layer (lower), and asking what's inside. +// */ +// // @alias('dereference', 'self') +// self: 'self', // a.self +// +// /** An arbitrary Ray, defining what continuing in this direction is equivalent to. */ +// terminal: 'terminal', // a.terminal +// }); +// } +// export namespace Binary { +// export type Type = (a: T, b: T) => T; +// export type Any = (keyof typeof Op.Binary.All) | Type; +// +// export const All = Op.all({ +// initial: 'initial', // a.initial = b +// self: 'self', // a.self = b +// terminal: 'terminal', // a.terminal = b +// +// /** +// * Concretely, we use here "whatever the JavaScript engine run on" as the thing which has power over the equivalence assumption we use to halt programs. - The asymmetry which allows the engine to make a distinction between each object. +// * +// * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=And%20there%20we%20have%20it%2C%20an%20infinity%2C%20loop%2C%20...%2C%20orbit%20if%20we%20ignore%20the%20difference. +// */ +// // @alias('is_none') +// is_orbit: 'is_orbit', // a.___instance === b.___instance +// }); +// } +// } +// +// export namespace Function { +// export const Get = ( +// property: TProperty +// ): (typeof Ray.Function.All)[TProperty] | undefined => Ray.Function.All[property as TProperty] ?? undefined; +// +// export namespace All { +// +// /** [ |-?] */ export const is_initial = Ray.Function.Self.Impl( +// self => self.initial().is_none() +// ); +// /** [--|--] */ export const is_vertex = Ray.Function.Self.Impl( +// self => self.is_initial().nor(self.is_terminal()) +// ); +// /** [?-| ] */ export const is_terminal = Ray.Function.Self.Impl( +// self => self.terminal().is_none() +// ); +// /** [ | ] */ export const is_reference = Ray.Function.Self.Impl( +// self => self.is_initial().and(self.is_terminal()) +// ); +// /** [?-| ] or [ |-?] */ export const is_boundary = Ray.Function.Self.Impl( +// self => self.is_initial().xor(self.is_terminal()) +// ); +// +// /** +// * This is basically what breaks the recursive structure. +// * +// * Tries for "global coherence", practically this just means self-reference, were no change is (inconsistently) assumed... +// * +// * --- +// * +// * Another way of interpreting a possible way of implementing it, is no matter how much more detail we would like to ask, the only thing we ever see is the same structure again (if we ignore the difference of us asking about that additional structure, that's still a possible handle on some difference). +// * +// * As a way of saying/.../assuming: I only 'infinitely' assume it's only this structure, "it seems to halt here". Note that this is necessarily an assumption. No guarantee of this can be made. This is necessarily an equivalence, ..., ignorance. +// * +// * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Quite%20similarly%20to%20the%20loops%2C%20I%20could%20be%20ignorant%20of%20additional%20structure%20by%20assuming%20it%27s%20not%20there. +// */ +// // TODO: is none, ref, init terminal as global equiv check kn the structure? as generalization ; yep, is_orbit. +// export const is_none = Ray.Op.Binary.All.is_orbit; +// export const is_some = Ray.Function.Self.Impl( +// self => self.is_none().not() +// ); +// +// /** +// * @see "Continuations as Equivalence (can often be done in parallel - not generally)": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence +// */ +// // @alias('merge, 'continues_with', 'compose') +// export const compose = Ray.Function.Self.Binary( +// (a, b) => a.terminal().equivalent(b.initial()) +// ); +// +// /** +// * "Composing an terminal & initial boundary" +// * - TODO: Note that an orbit is reversibility. ? +// * - TODO: Could represent this abstraction in another layer what we want to accomplish while the actual search is still taking place. +// * +// * - Like with 'copy' and all concepts: Note that we're only after reversibility after ignoring some difference. +// * +// * @see "Reversibility is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Another%20example%20of%20this%20is%20reversibility +// */ +// // @alias('modular', 'modulus', 'orbit', 'circle', 'repeats', 'infinitely') +// export const orbit = Ray.Function.Self.Binary( +// /** +// * - TODO: If we're only doing one end: This already assumes they are connected on the other end. +// * - TODO: should be a connection here, with is_composed ; or "reference.is_equivalent" so that you can drop one of the sides, or both. +// */ +// (a, b) => { +// b.last().compose(a.first()); +// a.first().compose(b.last()); +// +// return a; // ? +// } +// ); +// +// /** +// * Equivalence as "Composition of Ray." +// * +// * NOTE: +// * - An equivalence, is only a local equivalence, no global coherence of it can be guaranteed. And it is expensive work to edge towards global coherence. +// * - Though changes are only applied locally, their effects can be global (Take for instance, the example of adding to one Ray, which changes the perspective of everything connected to that Ray if they were to traverse the connection). +// * +// * @see https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=On%20Equivalences%20%26%20Inconsistencies +// */ +// export const equivalent = Ray.Function.Self.Binary( +// (a, b) => { +// // throw new NotImplementedError(); +// +// // TODO: This is close but not quite, use the shifting thing I wrote down a few days ago: (And then use something to break the self-reference) - Either on this side. compose, or outside the definitions +// // This one harder to do in parallel? +// return a.self().compose(b.self()); +// }); +// +// /** +// * If there exists an orbit between A & B anywhere on their equivalency functions - or: their .self - (except for the directions through which we're referencing them) +// * +// * Note the connection between 'is_orbit' vs 'is_equivalence'. They're essentially the same thing, but: +// * - in the case of 'is_equivalence' we directly have access to their difference but are explicitly ignoring them - in the context in which this functionality is called. +// * - in the case of 'is_orbit', we might need to do more complicated things to acknowledge their differences - we don't have direct access to them. +// * +// * TODO: (so dually connected, what if only one is aware??) Or basically just ; the answer in this particular instance is just if either end can find the other only once. Consistency of it defined on a more abstract level... +// * +// * a.self().traverse().is_orbit(b.self().traverse()) +// */ +// // @alias('includes', 'contains') ; (slightly different variants?) +// export const is_equivalent = is_composed.from_perspective_of(self => self.self()); +// // TODO: Either is_equiv or is_composed will likely change?. +// /** +// * a.traverse().is_orbit(b.traverse()) // Basically: does there exist a single connection between the two? +// */ +// export const is_composed = is_orbit.from_perspective_of(self => self.traverse()); // Needs some ref from Ray.Function.Self. +// +// /** +// * "Applying the same thing in a different context" +// * TODO: Somewhat related to Functors? +// */ +// export const from_perspective_of = Ray.Function.Self.Binary((a, b) => { throw new NotImplementedError(); }); +// +// export const traverse = Ray.Function.Self.Impl( +// (a) => { throw new NotImplementedError(); } +// ); +// +// // TODO: .terminal/.initial is self() vs self.not() +// export const next = Ray.Function.Self.Impl((self) => { +// throw new NotImplementedError(); +// return self; +// }); +// export const has_next = Ray.Function.Self.Impl((self) => self.next().is_some()); +// // @alias('end', 'result', 'back', 'output') +// export const last = Ray.Function.Self.Impl((self) => { +// throw new NotImplementedError(); +// return self; +// }); +// +// export const previous = Ray.Function.Self.Impl((self) => self.not().next()); +// // @alias() +// export const has_previous = Ray.Function.Self.Impl((self) => self.not().has_next()); +// // @alias('beginning', 'front') +// export const first = Ray.Function.Self.Impl((self) => self.not().last()); +// +// // @alias('not', 'reverse', 'swap', 'converse', 'negative', 'neg') +// // export const not = Ray.Function.Self.Impl(self => ); +// // self.terminal = self.initial(); +// // self.initial = self.terminal(); +// // self.not().not() = self +// // TODO: What's the difference in context between stepping after not / or not doing so. +// // TODO; OR BINARY? - "It's just always .next from some perspective?" +// // TODO: Level at which "not" is applied. +// export const not = Ray.Function.Self.Binary((a, b) => b); +// +// export const and = Ray.Function.Self.Binary((a, b) => { throw new NotImplementedError(); +// } ); +// export const or = Ray.Function.Self.Binary((a, b) => { +// throw new NotImplementedError(); +// return self; +// }); +// export const xor = Ray.Function.Self.Binary((a, b) => a.xnor(b).not()); +// export const xnor = Ray.Function.Self.Binary((a, b) => a.is_orbit(b)); // TODO: Could be 'is_equivalent' too? +// export const nand = Ray.Function.Self.Binary((a, b) => a.and(b).not()); +// export const nor = Ray.Function.Self.Binary((a, b) => a.or(b).not()); +// +// +// // @alias(`push_{last.alias}`) +// export const push_back = Ray.Function.Self.Binary( +// (a, b) => a.last().compose(b) +// ); +// // @alias(`push_{first.alias}`) +// export const push_front = Ray.Function.Self.Binary( +// (a, b) => b.compose(a.first()) +// ); +// +// /** +// * Performing a copy (realizing it) can be conceptualized as traversing the entire structure. (Where the 'entire structure' means the current instantiation of it - with many ignorances attached) +// * +// * - A problem with a copy, is that in or to be generalizable, it needs to alter all references to the thing it's copying to itself - this cannot be done with certainty. +// * - This copy does not do that. Instead, it is ignorant of other things referencing the thing it's copying. +// * - Additionally, a copy necessarily has some non-redundancy to it: +// * +// * @see "A copy is necessarily inconsistent": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=If%20I%20have%20one%20thing%20and%20I%20make%20a%20perfect%20copy +// */ +// // @alias('clone', 'duplicate') +// export const copy = Ray.Function.Self.Impl( +// // or +// // (self) => self.self.copy.reference() +// (self) => none().self = self.self.copy() +// +// // TODO Relies heavily on the execution layer to copy initial/terminal etc... ; and an is_orbit check before calling copy again. - Then again on the execution layer it can lazily do this copy (by not evaluating (i.e.) traversing everywhere), or it first does this traversing directly. +// ); +// +// /** +// * Placing existing structure on a new Reference, Boundary or Vertex: +// */ +// // TODO: These should allow as_vertex as zero-ary, but that means self = self_reference, not none. ? +// /** +// * Moving `self` to `.self` on an abstraction layer (higher). As a way of being able to describe `self`. +// * +// * TODO: the .reference might need two levels of abstraction higher, one to put it at the .self, another to reference that thing? (Depends a bit on the execution layer) +// */ +// export const as_reference = Ray.Function.Self.Impl( +// self => none().self = self +// ); +// +// // TODO as_reference.as_vertex instead of as_vertex ignorant by default? +// +// export const as_vertex = Ray.Function.Self.Impl((self) => { +// const vertex = Ray.Op.Zeroary.All.none(); +// vertex.initial = self_reference; +// vertex.terminal = self_reference; +// vertex.self = self; // TODO: Like this, ignorant vs non-ignorant? What to do here? +// +// return vertex; +// }); +// export const as_terminal = Ray.Function.Self.Impl((self) => { +// const terminal = Ray.Op.Zeroary.All.none(); +// terminal.initial = self_reference; +// // terminal.terminal = none; +// terminal.self = self; +// +// return terminal; +// }); +// export const as_initial = Ray.Function.Self.Impl((self) => { +// const initial = Ray.Op.Zeroary.All.none(); +// // initial.initial = none; +// initial.terminal = self_reference; +// initial.self = self; +// +// return initial; +// }); +// +// /** +// * Any arbitrary direction, where .not (or reversing the direction) relies on some memory mechanism +// */ +// export const memoized = Ray.Function.Self.Impl( +// self => { throw new NotImplementedError(); } +// ); +// } +// } +// +// /** JavaScript runtime conversions */ +// export const array = (array: T[]): Ray.Any => Ray.iterable(array); +// export const iterable = (iterable: Iterable): Ray.Any => Ray.iterator(iterable[Symbol.iterator]()); +// export const async_iterable = (async_iterable: AsyncIterable): Ray.Any => Ray.async_iterator(async_iterable[Symbol.asyncIterator]()); +// export const iterator = (iterator: Iterator): Ray.Any => { throw new NotImplementedError(); } +// export const async_iterator = (async_iterator: AsyncIterator): Ray.Any => { throw new NotImplementedError(); } +// export const generator = (generator: Generator): Ray.Any => Ray.iterator(generator); +// export const async_generator = (generator: AsyncGenerator): Ray.Any => Ray.async_iterator(generator); +// +// export const number = (number: number) => { throw new NotImplementedError(); } +// +// export const self_reference = Ray.Function.Self.Impl( +// self => self +// ); +// export const none = Ray.Op.Zeroary.All.none; // TODO FOR ALL OPS, ? automatic, or just put them here. +// +// // export const Boundary = { INITIAL: Type.INITIAL, TERMINAL: Type.TERMINAL }; TODO: LIST O +// +// // TODO CAN ALSO BE ZERO-ARY.. +// // @alias('resize', 'size', 'structure', 'length', 'duplicate', 'copy') -> Should be generalized as any kind of structure, but with this thing repeated on it. ; use traversal or ... +// export const size = Ray.Function.Self.Binary( +// (a, size) => { throw new NotImplementedError(); } +// ); +// // @alias('bit') +// export const boolean = size(2); +// +// export const vertex = Ray.Function.Self.Impl( +// (self) => { throw new NotImplementedError(); } +// ); +// export const initial = Ray.Function.Self.Impl( +// (self) => { throw new NotImplementedError(); } +// ); +// export const terminal = Ray.Function.Self.Impl( +// (self) => { throw new NotImplementedError(); } +// ); +// } +// +// export default Ray; \ No newline at end of file diff --git a/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx b/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx index c48eeee..ba589e2 100644 --- a/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx +++ b/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx @@ -11,15 +11,16 @@ import Arc from '../../lib/paper/layout/Arc'; import BR from "../../lib/paper/layout/BR"; import {Row} from "../../lib/layout/flexbox"; import Link from "../../lib/paper/layout/Link"; +import REFERENCES from "../../profiles/FadiShawki/FadiShawki"; export const _2024_02_NGI_GRANT_PROPOSAL: Content = { reference: { - title: "NGI Grant Proposal: (Hypergraphic) Version Control System through Rays", + title: "NGI Grant Proposal: OrbitMines' (Hypergraphic) Version Control System through Rays", subtitle: "", draft: true, link: 'https://orbitmines.com/archive/2024-02-ngi-grant-proposal', year: "2024", - date: "2024-01-30", + date: "2024-01-31", external: { }, organizations: [ORGANIZATIONS.orbitmines_research], @@ -28,6 +29,7 @@ export const _2024_02_NGI_GRANT_PROPOSAL: Content = { external: PROFILES.fadi_shawki.external?.filter((profile) => [ ORGANIZATIONS.github.key, ORGANIZATIONS.twitter.key, + ORGANIZATIONS.mastodon.key, ORGANIZATIONS.discord.key, ORGANIZATIONS.orcid.key, ].includes(profile.organization.key)) @@ -43,7 +45,7 @@ const _2024_02_NGI_GrantProposal = () => { const paper: Omit = { ..._2024_02_NGI_GRANT_PROPOSAL.reference, subtitle: renderable("", (value: any) => <> - A grant proposal to through + A grant proposal to through . In contrast to my previous application, which I realized was quite naive after a conversation with at : Hopefully this will serve as a concrete target problem to solve. ), pdf: { fonts: [JetBrainsMono], @@ -69,7 +71,7 @@ const _2024_02_NGI_GrantProposal = () => {
-
+
}>
@@ -85,7 +87,23 @@ const _2024_02_NGI_GrantProposal = () => { 50.000 €
+ There are no other funding sources other than my own in sustaining myself while doing research the last couple of years. +
+ + Hardware requirements: A or an equivalent in case of import-related issues. 15.000 USD excl VAT. Corrected for EUR, taxes, shipping costs and a small buffer in case of import issues: 17.500 EUR should suffice. + +
+ + 12.500 EUR to sustain myself for at least a year (any additional costs associated with the project will come out of this). + +
+ + 20.000 EUR to involve a second person in the project. (I might do something more non-trivial, but a second person is the simplest case) + +
+ + If the deciding factor for the grant is any of these. They can be relaxed according to what NLnet/NGI deems appropriate.
From 6430b2e49f39bbb129e047742cb5259f44a2496e Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 31 Jan 2024 13:51:23 +0100 Subject: [PATCH 136/138] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b9c550c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Fadi Shawki + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 78a70da71446691112f1dfa59bd3c3dd35cf6d89 Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 31 Jan 2024 14:18:59 +0100 Subject: [PATCH 137/138] 2024/01/31 - Fixes --- README.md | 8 +- orbitmines.com/package-lock.json | 111 +++++++++++------- .../src/@orbitmines/Visualization.tsx | 3 +- .../archive/2024.02.NGI.GrantProposal.tsx | 6 +- 4 files changed, 74 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 3dc044d..7b5fe84 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Most importantly, it is here as infrastructure. Infrastructure for the design an ## Where is OrbitMines going with this? - i.e. Future inquiries -Check out everything I've made public regarding this here: https://github.com/orbitmines/orbitmines.com/issues or equivalently, check the Discord channels grouped under the name: [Fractals of the Galaxy](https://discord.com/channels/1055502602365845534/1114584997702156388). +Check out everything I've made public regarding this here: [GitHub Issues](https://github.com/orbitmines/orbitmines.com/issues) or equivalently, check the Discord channels grouped under the name: [Fractals of the Galaxy](https://discord.com/channels/1055502602365845534/1114584997702156388). --- @@ -98,9 +98,5 @@ const terminal = Ray.boolean().orbit().size(2); ## License Magic -I'm not convinced putting licenses on the repo's in the usual case is anything other than *Minecraft servers putting "Not affiliated with Mojang" in their stores* just because everyone else does it. But here: after doing absolutely no research into the international ramifications: [LICENSE](./LICENSE) a license for those who like to look at them. Try to reason to what that applies in this repository, obviously that doesn't cover everything not made by me or other contributions to OrbitMines or something. - - - - +I'm not convinced putting licenses on the repo's in the usual case is anything other than *Minecraft servers putting "Not affiliated with Mojang" in their stores* just because everyone else does it. But here: after doing absolutely no research into the international ramifications: [LICENSE](./LICENSE) a license for those who like to look at them. Try to reason to what that applies in this repository, obviously that doesn't cover everything not made by me or other contributions to OrbitMines or something. Just put a reference to me or this project somewhere if it's remotely interesting to you. diff --git a/orbitmines.com/package-lock.json b/orbitmines.com/package-lock.json index 38f9b14..c5d6297 100644 --- a/orbitmines.com/package-lock.json +++ b/orbitmines.com/package-lock.json @@ -61,11 +61,10 @@ "../environments/javascript/@orbitmines/rays": { "version": "0.1.0", "dependencies": { - "lodash": "^4.17.21" + "@orbitmines/js": "file:../js" }, "devDependencies": { "@types/jest": "^29.5.11", - "@types/lodash": "^4.14.194", "@types/node": "^20.1.0", "jest": "^29.7.0", "tree-sitter": "^0.20.6", @@ -4425,9 +4424,9 @@ "integrity": "sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==" }, "node_modules/@react-three/drei": { - "version": "9.88.16", - "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.88.16.tgz", - "integrity": "sha512-AcDTRVmXL81KYQvEz7XSxUqj0W5s8c5XgtYzAx+ttB86tEAxp3r7DXc6ZZdMAUZyfw5BSPHx9hKMHr4xmoFdPg==", + "version": "9.97.0", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.97.0.tgz", + "integrity": "sha512-D7qNQDbEoYHMlJU0tr/f/rCmw1TQmI+INEGGrfoAEA+sIvqLw9wLCra+1+t22lEPCpdpmVSMmdv6PynMcv5tCQ==", "dependencies": { "@babel/runtime": "^7.11.2", "@mediapipe/tasks-vision": "0.10.8", @@ -4437,22 +4436,20 @@ "cross-env": "^7.0.3", "detect-gpu": "^5.0.28", "glsl-noise": "^0.0.0", - "lodash.clamp": "^4.0.3", - "lodash.omit": "^4.5.0", - "lodash.pick": "^4.4.0", - "maath": "^0.9.0", + "maath": "^0.10.7", "meshline": "^3.1.6", "react-composer": "^5.0.3", "react-merge-refs": "^1.1.0", - "stats-gl": "^1.0.4", + "stats-gl": "^2.0.0", "stats.js": "^0.17.0", "suspend-react": "^0.1.3", - "three-mesh-bvh": "^0.6.7", - "three-stdlib": "^2.28.0", + "three-mesh-bvh": "^0.7.0", + "three-stdlib": "^2.29.4", "troika-three-text": "^0.47.2", + "tunnel-rat": "^0.1.2", "utility-types": "^3.10.0", "uuid": "^9.0.1", - "zustand": "^3.5.13" + "zustand": "^3.7.1" }, "peerDependencies": { "@react-three/fiber": ">=8.0", @@ -10372,9 +10369,9 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", @@ -15781,11 +15778,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/lodash.clamp": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/lodash.clamp/-/lodash.clamp-4.0.3.tgz", - "integrity": "sha512-HvzRFWjtcguTW7yd8NJBshuNaCa8aqNFtnswdT7f/cMd/1YKy5Zzoq4W/Oxvnx9l7aeY258uSdDfM793+eLsVg==" - }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -15801,16 +15793,6 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, - "node_modules/lodash.omit": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", - "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==" - }, - "node_modules/lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" - }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -15859,9 +15841,9 @@ } }, "node_modules/maath": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/maath/-/maath-0.9.0.tgz", - "integrity": "sha512-aAR8hoUqPxlsU8VOxkS9y37jhUzdUxM017NpCuxFU1Gk+nMaZASZxymZrV8LRSHzRk/watlbfyNKu6XPUhCFrQ==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.7.tgz", + "integrity": "sha512-zQ2xd7dNOIVTjAS+hj22fyj1EFYmOJX6tzKjZ92r6WDoq8hyFxjuGA2q950tmR4iC/EKXoMQdSipkaJVuUHDTg==", "peerDependencies": { "@types/three": ">=0.144.0", "three": ">=0.144.0" @@ -21745,9 +21727,9 @@ } }, "node_modules/stats-gl": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-1.0.7.tgz", - "integrity": "sha512-vZI82CjefSxLC1bjw36z28v0+QE9rJKymGlXtfWu+ipW70ZEAwa4EbO4LxluAfLfpqiaAS04NzpYBRLDeAwYWQ==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.0.1.tgz", + "integrity": "sha512-EhFm1AxoSBK3MflkFawZ4jmOX1dWu0nBAtCpvGxGsondEvCpsohbpRpM8pi8UAcxG5eRsDsCiRcxdH20j3Rp9A==" }, "node_modules/stats.js": { "version": "0.17.0", @@ -22528,17 +22510,17 @@ "integrity": "sha512-Ff9zIpSfkkqcBcpdiFo2f35vA9ZucO+N8TNacJOqaEE6DrB0eufItVMib8bK8Pcju/ZNT6a7blE1GhTpkdsILw==" }, "node_modules/three-mesh-bvh": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.6.8.tgz", - "integrity": "sha512-EGebF9DZx1S8+7OZYNNTT80GXJZVf+UYXD/HyTg/e2kR/ApofIFfUS4ZzIHNnUVIadpnLSzM4n96wX+l7GMbnQ==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.7.1.tgz", + "integrity": "sha512-63xvjnmK3FpA41klHfVvTMi2JRFdKeu3b4STBcLvGyDMYRpkBIyJ2d77CnNvKBZl9bed4sdEyrqE3AOsGorjUA==", "peerDependencies": { "three": ">= 0.151.0" } }, "node_modules/three-stdlib": { - "version": "2.28.5", - "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.28.5.tgz", - "integrity": "sha512-JdLMhkpT+1ZWeQPyKQNW1zqUwISI2hsUljS6u3vB9lp5EvwsayaAzGnbVeR35895udOF+zxcTiQY3psk+qqlxg==", + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.29.4.tgz", + "integrity": "sha512-XNzGCrz/uAk9XoLwd35eN7dQyI4ggXZTeqjcN034YdYBpBlNO9kmLHehl/0Nw9jCelblB7jla+unHAOIyLyV6Q==", "dependencies": { "@types/draco3d": "^1.4.0", "@types/offscreencanvas": "^2019.6.4", @@ -23011,6 +22993,41 @@ "node": "*" } }, + "node_modules/tunnel-rat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz", + "integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==", + "dependencies": { + "zustand": "^4.3.2" + } + }, + "node_modules/tunnel-rat/node_modules/zustand": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.0.tgz", + "integrity": "sha512-zlVFqS5TQ21nwijjhJlx4f9iGrXSL0o/+Dpy4txAP22miJ8Ti6c1Ol1RLNN98BMib83lmDH/2KmLwaNXpjrO1A==", + "dependencies": { + "use-sync-external-store": "1.2.0" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -23447,6 +23464,14 @@ "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", "dev": true }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", diff --git a/orbitmines.com/src/@orbitmines/Visualization.tsx b/orbitmines.com/src/@orbitmines/Visualization.tsx index 215553e..79c4569 100644 --- a/orbitmines.com/src/@orbitmines/Visualization.tsx +++ b/orbitmines.com/src/@orbitmines/Visualization.tsx @@ -9,7 +9,6 @@ import isWebGLAvailable = WEBGL.isWebGLAvailable; import {PaperProps} from "../lib/paper/Paper"; import {Children} from "../lib/typescript/React"; import {Col, Row} from "../lib/layout/flexbox"; -import Ray from "@orbitmines/rays"; export const NoWebGL = () => { return
No WebGL
@@ -20,7 +19,7 @@ export type VisualizationProps = { alt: string, } -const Visualization = ({ray}: { ray: Ray.Any }) => { +const Visualization = ({}: { }) => { return diff --git a/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx b/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx index ba589e2..fb1b60a 100644 --- a/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx +++ b/orbitmines.com/src/routes/archive/2024.02.NGI.GrantProposal.tsx @@ -91,15 +91,15 @@ const _2024_02_NGI_GrantProposal = () => {
- Hardware requirements: A or an equivalent in case of import-related issues. 15.000 USD excl VAT. Corrected for EUR, taxes, shipping costs and a small buffer in case of import issues: 17.500 EUR should suffice. + - Hardware requirements: A or an equivalent in case of import-related issues. 15.000 USD excl VAT. Corrected for EUR, taxes, shipping costs and a small buffer in case of import issues: 17.500 EUR should suffice.
- 12.500 EUR to sustain myself for at least a year (any additional costs associated with the project will come out of this). + - 12.500 EUR to sustain myself for at least a year (any additional costs associated with the project will come out of this).
- 20.000 EUR to involve a second person in the project. (I might do something more non-trivial, but a second person is the simplest case) + - 20.000 EUR to involve a second person in the project. (I might do something more non-trivial, but a second person is the simplest case)
From 20d5bd23289790ef01ef31b1e0475664a5e13beb Mon Sep 17 00:00:00 2001 From: Fadi Shawki Date: Wed, 31 Jan 2024 14:57:09 +0100 Subject: [PATCH 138/138] 2024/01/31 - NGI Grant Proposal: OrbitMines' (Hypergraphic) Version Control System through Rays --- .../archive/2024-02-ngi-grant-proposal.jpeg | Bin 0 -> 1713018 bytes .../archive/2024-02-ngi-grant-proposal.pdf | Bin 0 -> 39936 bytes .../font/fonts/blueprintjs/BlueprintIcons.ts | 12 +++++ .../archive/2024.02.NGI.GrantProposal.tsx | 42 +++++++++++++++--- 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 orbitmines.com/public/archive/2024-02-ngi-grant-proposal.jpeg create mode 100644 orbitmines.com/public/archive/2024-02-ngi-grant-proposal.pdf create mode 100755 orbitmines.com/src/lib/layout/font/fonts/blueprintjs/BlueprintIcons.ts diff --git a/orbitmines.com/public/archive/2024-02-ngi-grant-proposal.jpeg b/orbitmines.com/public/archive/2024-02-ngi-grant-proposal.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..00002ada7c062e8211534f2a9880029f4c983612 GIT binary patch literal 1713018 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

LVjnM8W!0~1O5gvf5&`}mnphm_jD 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%0DACe-O3CpV(#$q%wF>ttq?^z$A6e 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 !X(J#qlYJS3 z){GwfsEOL<9BSf*kVm{bODO>cy1}n1(3_?BAH@)k;zd57iUj9qtXvIogtlTpIs$5T z+wE^R2-Xz{KT%qt|KY%9sdZ4I_PnTffA*%C8cK@Wk`5YPTr@BKc|3#}7+|PLxNFyw z@^PRAeiu()vVr1~&(EpQM*$1Tb(1&Ty$Zojaw#U<9pN4|rMp6Aqq{j9G4l%WXj@My zJ|Gux0D+Mz{K!~kH|&59W=C{*$pPBCY2+PqT6*dMJsaaOvGy_-I`gJ zapB_37yZ;xN5`QETLACaizZe{50Wd>gh~oEzg{Mg$88CG2?sT8O0d1>b4=jZJ`-2} z2pm(3SlGkP?^^A05YX`%otKdnTTuG+=b%m4Z7FSPMoLAgR{Ir=m4GfyeOzt0V`-DV zEMW>(-sESEc2CL)NSmBpOTLy4EO1X3NVBH8{p+6T^yy0Uq{4VRkR4t4 zzUav#R>j3!bYxfeV_^DCllUN^{Vh7P)^r)*7kXhS4SX$dMD~0kJ)h?hAAilZ#dRQ1 z{4_9W zS{+9|c?YvOlyi=-g#P|0qzQsPwsPC)uYW7pkWdDc&JAZSAPo4LA%-+gv|_nj(q?Lg zoTsFUnBxQ`7Vb8agZ{mLzMNJe8sSWURef}v zaf(yD0(iAXwSv=~r^Sige=f{3ASMwkc!2$MlOB(m)(}1=BKO5^tYwF#9sb&j{Umdj z{JKqmitIh*MB?qrMtG5fSMcLQfu~2Cmx=6X)b8S^t3^E;Rh3_c5>^rjZqU-o5hDU9 z4*yXYj~YBIA@5KYFUPqmOprcE75`r{@B1%MF+@whe}4TBYr}u>br7!T3YP!w_pxH5 z)Njzsx7O`4HcKXJ{hX4vJ2fLH>#LAr-7%3W-s$%vN%UU z+?7$@amD34EWNT01z1c8nuvwFGPIzoYY8wP3U&4HIK(WMZtQMqt5dVt^k(5k_$zBj z%+jsEwB(MBq!f$q-~151-x`(#zxg$Xobuw(kJCkZ>o!6eMUN=a_4gJpk=ztMU%-y8 zmdl$ASWO!Mn@Y9n>}Ss@kLdQ!-{K__jd1`^qE=nIvv0!mRkr7_q@s^3F3#xTB@9Dk>}J9xW@+-c2) z@{v0IONCMea7vfi?%Q6ODz?WG1|yxP4csmwcwq-4hDCORHZR?6v__dr z04oo%KUNEqS~9NJ=l&%blS!UM7H}?M%Re!=_|)kA_+XKJjW!`(gfa2D5Gz8JbMHMh ziR~i-Vm`8<37k@yo`pp|1WAAt`U7>}!J}hs#ZMik1F!JvUFo8(lD?(^P6zHA(Mci% zb=QWTUE#6gthDI`2;jV-(EXjccpsCa)CGSGS=iA`TzzN;nGdFdJ6tWh6hl~?wWes^eJShtJ5e4+eG*-^Pv%O;|J z?+1vW?r)}7u(83v*MTcMY&v|#umhU0LTLQjz-@;g35tk-le!dO6PXscX5V`)TqB!= z)WU4E%VPZ#i;f0(?o?o>yn0b$$MoPn-H@wM?ptJBB|xfZ z^>$67Ef-L>(D8%^Y{omLql1&iL4=J_n{h6q0s((XdOfq7;A^z7_?vDzSjetlJA;m> zQAYy(9b<7uWr>KNWG$ILmVP*g21k|r)`etCAxkrOLnFRF}CXw*sWN@g^?cN-Caq$a}tVOKIdsb~Ke(RY0<= z?CIIf4DMugutVu<)f&Z{Q9e`R(~hMO9V2@tR2C0+VZ)AlX1-T4P2mrUd^{ss8feUmzQ_%{@#$a#uaRR0h;>mi*YP%iT#IR~2>ZUp#(By3@$oUli7>UdsyK z)w|6qCdX{L(obph1AnbNXgkS}n z^yWSG7k$s1obp9H(8f_FwsZ`&D|$GDsc?^A+ZT)E`%?5Xi1tRH_ipg7>GCs1)S3lC zIC@9pMj`JLcQsYPcE7lP4=V8Te~p z#7V58I&T+jIn_Y9j1ewkj_N|vfU-i6hLcezQ-_Y&BVTqzNO@1m1O*;t-e7cS`dP>9 z9+@x2SsUDt<=WjUq<5%FuIrsFS=#$~fkT|%U^m~qi9Dq+p6`=dci!ium}&X>R+ldF zQ{3aF$gtNnj^}Gm5INesk!T1SHpA6-=u*Ca`5M#Ka=-)CiarpgG9{{n-}(HV*JWhyM>F2jcZe7o{MRDCBcT13zLHCT<+Y_6SWixjU>rLVRIqqI1T(!UzN%;?vdH>&|#@6DeE4=3RMn^uvHhJjY^M!m2vdlbSuVC$$gkt|DXLj^Q0~-r?lTvdl_(W7DkzdMIj>%^HGFhSTv!y`0C4Bc7$ZO?>Pc?9aT=TjiHZ3U z1*1@bIB7z#nO8?vob|uNoshK9%S_V#<XV1?{Pu$60G;7PO2I4suuPq@i33ecBID7L@*aHc(ud?f?H*S7oJhM==_@l_`moy z`F}@v_MavBmxz}Cw7CEOeK%z-ovy2HUcGa-VryCttXt?8dvF-6RdUqYhJOz@VbeX* zSPxXFB`8#C%^h8#+mv<-1Hr^T<+Jgtql+|L;L^hj0C9jTbL%gOqRk-mIJm)m>T+UB ze*f+jb8>LjjlU$hmD!tHM7^B2!JRhClg}1^mZ~q-*e-9zoLJbO$H0Q2=MS1g{*r`q z<*dFS;!p(b8_yMHtgFu}CjW;&x0aijx>{t(!3VYPK5m=uu|FG9Al!Yl(>i#`yGdo_C9!dKg`KJ-7<#^slJC?37h#ybPaJ3~q-H z9^?ie(u?5(b9SEn^U(i&8~<79e~!mLf%wncSUHwxNIm!J zPk!`+%Ql0ZU|xr`_;SLfLjIxr5Q#z^AvmwiU?Xs1{Br$j@XH~FFd^r(ZPA}Fp+RW6 zQrmF*|NUnAPi^*3{rx|02lG#~{8N?x)2;fin;K+WRx`Ulo;Un@e(rfJs6JM=(jqRg z1(#rXpJvEgpK06Vt^{>2DqH%q%mR4F{))}*?B&fI!d9BXBT)u?#zT>$!(xY*l*xIC znb?9#jqHsx16MTteOV+x{i!3rGz8^+cJ#V9aIRnC6PH`Ns%Js16CN#Ty(6egtU$ z^W`0CkN7lQ!$6uNi(ehwY^?Y%*FMNpb7h`M(cOQmVD)p(Y3(KH&wD@-^zvD1ch#Wn zwQ12;{V9(dp7zr)hd7p`GVO0XANQ|2sY^l8Ywwog z3^cIIWhCzGA76Gqyr(Xc(a9O@ll|+>kRr{!82M2zEY|zJ>Q@*x8lvxY2J0U((_8Xd zB@XJQHFKET$}j6T40yYeQ|cRhnexy6gxWwl^wcZ`UYou9A-cUV-$N$+DiA*Ly?lwJ zC-LSNA^9qkQaKOa7Dbi|GaDMBFxj3E;76S@YB8*(T(V+_PsLRHGB#0Jo>3UtTxAXn_9{yN-|5;M?^iQSfnvg{0zvzLMQ$UOM6}Zo6KR)dvs^9u_rA z2}|iiI9&AYcX>IK*ETC zuF3UFYX#{wSnu@^P^HhU%2FQz6o25$*NQJE#rMu$68On~d@u~khBPhyP-NhKN5f4x zUm0XcW$tMbQLr#8j?eZd7`@w2c5!p?uGyT;s3=L2mW0D0f0SyFviK}|-z~>PG^gY> z?bs2R!FN7M7jao{rkxD%Yi8c%_s>{mwYh5S=h=l|zEyWOaNs~i3-Mo;e2pm&r|R2Plb)J&npLBpX~b9Z0%L}Q4oM$UzYGfFEg8a1o0 z?@+_&zN+UW|Hleyfr!dKjT;gv&dJUus+G?YaQh0?SV@9K|Ha(V#Nb&4kqEx)x;1j< zt+iq?UyltUYN~&UPp`w4*PgZ|lr%-9R;}?(F%Hbc@KI*oc9d8rQBNedhHYz9DMc&? z2D5S+8fOD+8Z~_LL=v?{q%NZ!(;K&unOu()x8ca?(bcIMFOURre6Q9fs{77@)%2sa zp{|eZD%bL;+=GE%k-&B)N>*#*2#?cIMNLMjxfh;~4goJ4Kk;uz*D@%0NqgdW`zOk?T+h*PC1rLvq=4ax5S^!qL)ni8e>@U`iv ztCl(Lyo-`LpFT5S`D(|B|Fb`{eVzez!5r({)qhEF`(yx|hcPs!`{k=HG%I2HpqC=?eo^f?%A2aucUv>$(iB2!6A_abImIHC0>WHhW07VEu|Kvz#Ii zMWPYup<7(9?>rKKi!sqi32iB_sTkVi>y&7~?p+3p-G&c&GfR#?RPA$G+{<_~^;P@# z-i;n9+N}ftfK<8b!shHClvJA4=sXlxEt*F0k#BcbcjAf@Uh2TiS&%!b1L4dT#*1iG z+|&WNXcBcrySU&Sd$F_Z>D}gyD`&}TDhgUapKpmu)#0px(H?BYWL5>Ptm+qgO^JuN z$ttn{><*f2dpFcr#xZU-thBCju^M#pLvwEA+{1q56{~H|rd(@VKUJVW$0cC+F;RM^ zv>AXPsAI3K z15dNjQZ{`Y6Kxx!`th?-dPd&%)4^q~mr{Tx@Thim&JCCIF&6H8aIkf(l*Ui5T5j|+ zi1!Z*820kcD#Lsa53XXe)AFKlXtXJ`@CFMi9^!t}@p9epQSDEqzN&W;^gCt%BO{~7 zAFsm8&1zx8X6D;p=w05x6ed99AhW#D3`9uuOx0)sv9-R#oR_?Um2aU)^?KN@jC~lb zy$d*|kp9X=&3o6w`+WoFLh-v1D!ECwo2J*UHSSuaH!!C?RK;zSir6&zA;_*yb%Q1M z?9Gt#1&PcwkO~U{KcQALoxS^+npbKoWG>@YT8i$W^6X?3k+1yH?b$wQ7y8Z!C{jrTl)p}lrS=={`+aY= z*kX)mwH@Z)JOK1nPtIp1V<1 zA9}mN%MW#JN3`W^i2GHiB7{CQ*oIh)v}e*Fxq>Goy2fHRXC0fjWsNRb?xJ6}V3glk zTYa|LjE-bvTBCqYHfkNEd?uaB2s7TUD3x@Zmts2G%~9r3FpZ)~#PGKCZd-yqy_G$p zOfvKchn&$gA%rXBdq9mKQ3jReM- zLJYyDln`_oYsA0wcbB_C1Uo_ z`;pgu&-&A;cjq03&GdlL_?PSTDce#Yn4=HZNJK3Rt2gng|Hz2w09ur>DUNq=k_gKv z?Xdo0o3?HaVaQl_&h!0~{bFfE$wkM5Y4kOd3I!YYVToID?uAA9p%rMquT`~ky8Cqz z4sUQ^wLyub?YHqq!S1|WD~b@kv2q7C%k5@@04Dd7(Tv?B=!v^8XCyXW0x0m})G&iy z;5zKv-ACigsltlWRdcE_Q#+*+w;BxWwVj*7f+XDsRRfN6XSTU#a?&PfD`s1SFIj6P zJ0CD~K1|7RUC*do)OeLG)aR7{YQj6m3Xi<2e;_4E9{1jlqF=F^D=wbCy8D-#mk)iy zh=$9NW$yK&ZzkM($}#a5>c&-ylG#~&FLjeN^fj|~%bO2@`~f4KBDYwSIT7xm;8LO| z^2Pz4aGs7|ITOS*p1xaeXwf(QrSDSlGM3)OfZA)xD=j8C&;g@SSn>f^q~@f>knA&u zePi|@Z>HhFWL}WGJLcl;QnO@!Y!Nc~>&U*aexRIC7H5U=ZIp?t!g*CIijY@hoFd{1 zs&`E1d#B2XD6rNa4|SZ45)T~BNE(~;K-i>5yjVnC`x)up9u#@V(0auj);|&(Jxmi^ zqpJn`Sy+0Qw}gmF>V%xlpv_Dx8W;1n98~VORB~6r_s3OUyAhE&+vF)3^c zl~KO9u_5nDK0E3L9R49t+e_QVI+{cK9@Os792>FLGB~(+NYgj>)1}QzP}~! z^FBVOKUGm}KyBwG?SLM%40ycR*I^o^xEIu9nUM)_Zk})tHX=~$_7|A&uy({~dgnzi}%1eKW=Zg4!gUB9Z!bCpHR6G4MWy#eJ;Sk3OWxg zIO#H0!6Rp%J4dy(prBca+NHU^&ZuUuQ&U@Gsb{2lb)&6}&I2-1XCM=hYx;-L&MJ|g z!_^DxHvaQ|j6Q=skec&$BxpCgDM3}EjTTkG#dBizP4$&&X#*W|F=jx=rOI?>nZiLu zII*Z)#~T`e#Q%Y)h>k|XG5IlVOTPw}O&SR44eKTq*-w(==SvpcikAYn6iz{2s+$p6 z`gyP<@v9g5?1VQt%W|R`bM;EoE~%G;YXG|-_VAJMR&;?qZ;76RRSGz>HaIPdS4CUL z5#NkkKa%lZ`Buqq5jj9-o<+3O8Q$kpLi+kf+|EltD&6%{u>sP5qPXtXvodE`RA{!< zVQ&FyuPiCfGbt8oE9Rc@63^sZ%p5Ii3MdVjYXdA*0yhRd8V$9iyHqc2k_mhBfP1)k zdZ%Yo_AuwdLX{1eVR~@Y3*d3**=a>-Iw5^+vEx|UMSa(6d_t?}Y@KabPHM``(>N{V zldI4c=FGJle`&(#z=bk3(WteH$j3BsV^`Xe8k~pI*1fWs4A;#o)yvggbYvOCSY<&S zkq@tznv09`l|BHe&1K-BFQ{-YbAUUMKI=qP?O2e}E3+nuN;1wtHwudNz%6DbKaHu$ z@92?&LL|5=wo-J(P}|tD?0aX_jd?$q$K!bL5R=!_p?9G6!W>b(&IHRTdeETQ+nWaF z0@Ww!!t+nsYdtcOYNpVUC7A5QjNys&{W|eKr**9L9AG)#<}u^NbgeI51eWvtn?ZJ@ zZ2^00UzisMH6j_eM|K$Q8TFgJYw;*PcHC`(sZ0AzH5HyXr~3=elP2rp6Sd5mHx>Sp zkpCsIQ2;U+8jCb%{Uteo3ph`PKFBCWtC#!bl=)4|vg_2{<@@mRj5k2CC0@0oY)D)_sW(;fY_v)~N#J(^@x&h)G(a4>Kw7#wLdxPb>zplSCTPt5foYOy zp%jDia?vVeHGM!n$D=i1qNjkEcP+vD-S?tEcdZcj_QBCc-~0LZMZo~Uhs+;s%o10i zY?=7hMjsTsk=##$Yt|omvbFjx|EJW1t-{>7664ulk}%&Q;(Gtd34DH)^CkXDb=u+= zGMEJx8|yG*@uV_?(Umv7i(>4!MC!LqQFq#d6Tj{VvQfKyHEFm0C}VQoKjyJhc^?B+ zw-5?6drfxhg@eEbEn`tgX)=>5%A$zEkuy1qv#Oo|T{`H>790A1rlTs!Gho5fBGM1V z$rQ;XLEpY;Z!+34r7L+D%rVa1xRV@&+&c;3q^euXN1fblb)GuUqeyKqgQOPVl=Vhk zh9)xUu^6CRK}Ln6!$G2Fa;D8LU#kQ5d_HMsXj67$raAmj5ACrh`{wS@&O%X0?t4rn zsr5je-#r^=M`IW4=gJ*@x3+Tn;fYWK*kw;(cLV#Sy>xQHvfTDr64;V|o@>evzrT%f zc*zIRc#zb8o+4^_z%vP-G>Ry-7%7fSBMH9FTs8kS+{)QQumw`BEOl6&Mn&?A)p-so zuDF(Zdcq;4yBYq*GxW2OaQx2=@rfi!lm}R(WrQH;Rb=a+EHNO8@M&}194iJR4Gn9} zZh3i@1&9l6aUU5vjw}>~vv~5e)wk812QOBnsde3USourhoHKEeDtfhjUU!*|By66$ zvjA17L(~iV@q32-L9a(cJaoL>7waZ&9pxBKmNn=hpK#LC)jFE{WQ8p)e2hB>42`JA zndlc&kE`ZVD4&1ryz&bn#@rQt{Gf|y9GQ)jw`nyQEv#*7#xIUH!kFl{&l)SVM$ghx z_)cOMy9K%43)DQ`k8qx9w;v%FLa;(PqNN3gSxh+1NXb%3K&b6$ZiK2lyMex|wjy%2 z#x0*-U1~hL>~LEpJ)o%Ef@PSCd?2IARD5ljb+@TITs>?fqKT1ES^4q0J>!s>?<1HD zw0hO&w>!=llJkh&S#%#Ihull5h*?cu*45DAJQF~ zl}ocThRl1Co-_?>G5d7b$zF{XXBB_9kT*!duk3Evu5}!x%*8j_zFKzq-O_OFX99o2 zg;#;OWvP7cW8K_dHOnH?I%SpaR-}xc`G|;q5!{ur(V5A^uj)Fk$EvUhJ#gj zPN>Pb2jH|Me74k`7}6SAiC)28#I#l2dYYjrN>IO{vT=dSnNveEJEba%bcexOAg#q;Ce8k(Z8ZFwOXTmQD5sRzm?)c!%bEMdy` z)e&SF-@vCS-xi#kZ?HXNhOAZEXfXNU>_JMo+b5+6_l2JZu*M+v^v1{8JUjq^I0714 zV#yWf&loig$84hdR=S-;b#0j!_rsx{boR8U-$@qFGb|stxpz0b9(f?hB?;DDy~7IK zZ2z!DLcY6be=}3ecGGIW<-Ny7P?N!gqid7TGM;dJEmr!f7r8fCjl4fq%l$g*y{kQYcG;q<`jb+% zX3uk)BcA?~2|Px_+!GZ;Cm{gDqeVonITRlu+V!T(7AtAA{NpAoWzZrMor_qU2|wpc zb~U$WRyM_oDdzMckdC!O>jtOA4bDZS+M}ytV1^5Nc6$@bc($8<#)aYoIZCkfmT+#e znOyYdCYlP39=DC2QH7r5t&H<1%dY2JEtK2G^W+LDE8Vp+BabUuj8kr~!b;vBkQe)1 zt4E3JQgaUW_Fr$jVn3t6XxUV)EX(bnM+>2jEv`t9;zE{&(hA+xkroQ^4W|%Q=p_5X z{IU-0y-^z*g^giAAZ>nbSJ#wte@V3mHD596SvUVCHmZKYTNc%5oSQt&p6=-f_wdR< z3s>$;#^})rR9LLj)1l+*4#mEF8ZfmQVw&^{d#7aG6_hY+``mDF3{(|+ zAY`QO=#mi)5{}9$G{q9;O03B{AZEUSMl4>Clc(#rWJ{kxmCjHN?pf7le)-40^2s-Y z7q#Ce&@05hv+3Cf25RRTp?7yQWC`(!9;FJ36eG@Y_EG?V3Yb|cgsVOi$Jzsg>Wy;&Qdt#y+7l(Grvd^ zfcVX6S~}%DEd`qbo0N^0)ZTU|C?o61RH~C$y*D;F0{N1&3T`LsSFMw$v1%Qvy~ls1T{QBLPzOuv z*>)n0XW2r0U19UA3Ud^1YLt~A8*7+cT>rM`p4ELB(ur=hss%%N2J!Es>6Gk~4QFJt zDQ<+9=R0~<)l_q;Dm`_Kb7Nz8bH8->7(5XU;_twk1e)wPK6?WaDB4w+_+q#5AUPIvhN@4qCl#joKKlspGK9bRx38q`#0Im@5E$CI_Gy# zyTmnm#YbdXS(61A0o+9c(bsnJQQPf4+2T%L%mWsY_wlAK518?!E8!7Nu z1Gp?-7KHUhiE4jNHu*~S=k} zvBQ(8Y%1Siu>FS-yXZZuz6dHgp77XrbDjBVWPou2dt$8o!b9fj<=^S$z@uL;<628!)0>v>B!uxC%f8XL*gwid@_X* z^z+n`=LM~u(ML}Bfx)NS$Lt&E!P{$Mi6=g1dQ zLgodlmz_~mFfi%RUlOQYUkTAom|45(d6AE58h^ z14^EANx*HyOtK`l_HeHJqHZh6gYk0p>!Mug_ zeFNsGnfqBbT<+DB1;;;t$s`?1;brRF)Acs7;@?TA0yAB9p?!_g>C0eXXrV6w1Iv_ zE$aLZ)N8Xv<~(8c-}s)kRj2nhTD`bpj_HI#<>W~M%4h%qZa*D{iyHzn-|?$)H6%MH zagtY(9v33{Tk*4{(Dck|-M+KsL2ZIMFA>>}hg?s$85`{eM($A8}zVK3x+zYvk0 zA>r9^vY4E7WK^qt%SQ@v8DJT0^&_#DJ`o*wD9r6@k~#xmi2cY#w`*5`Xy#^YrWES8VwVLM2{ zPH(-aQC2SU(D%w=k>Hv42{Ecqm@YV#QS?)aM_~8e6Cn2k3eSY2;t@9xHI*IMXU> zK*k;9)^9Y@jNC)^H!F9^J)8aGf3=tCojEeV_TYgo=+TeG!zJqKwAxR!pX(>OIOck7 z@07ka+N}xL{x(rUb)oZGwV3Mr4Lp~eDxmZJGh=rx{_R=^>(B`-gLX)aDZ(W%i?ck) z_lTfx181WOIMF%`|FujbrVp|SUzC5G>ZJ}M_S>_QljO;tkl zvuJk%Ys4$`&0?)LTWCoLXI)^S;9&GIGG8>eMu*w$Htg~Ie z5q_``OpNvJDXmTA^10o2fP#-_e1lz-Wy9A5f>OhX;^{3HPfuC_w0*%E)$bBS0<<7< z?mMNft1VJ}E9z38iVBjTZ4I#~8(SmKqV2s*CbKqag?Xi0UbBBmm{_~ES)HnGjQ4Xr z-9c9VH}>8usL3!~*S4Xepn~)&y@T`)(hV4p8ah%XROuZQ>7n z0@7>f0YY=LXCLjEwa@myXRUwM={J+3%=aem^W67!Npb2LN03-1Rj^R7dQ)tY;go6R zVqVhNLVju`6a+AHy$ZAvBlzGP^!Pe~bK6luP3M+g69Z|ym7__WELqDOkM?SK#9M8j ziHGgbb?D=MtV%D+YXu$uyTf$7h}qA-9TB%5U$+0dGmF2T*_K&fMN|2yWlGil-l52| zWypN%sIC-K1;^39au=^@ep~l~i-?5n=|iK|FvDcl-*-LoiOKxLKbt0Lmv&_#Vk}US zj+*baXUAOJAPv6Yn_e@{9!-<9V&uh5*^vLgJ84a&euu~ES7C>#6qAL@ncL!51@;q- z%4-^6fdT9@J~3js1V-Rj-6yVPKe&oajrrPDcAx+e3ciFwa&LE4590()XX*Hpu?i3n zbnFT_0O_$HF|zD`?)Tz3lL|Xh^+LO4wl+<2?RYh>Sz$ewB?Dwo(&@FG z0ds+<3((rtoagbbKz;Bb-F_}%UYm_n>@J4wn>FPyH-(o0LRD%9Mug=D#|hqD`W@>ger zmXD|!^BOoJ6L>C;uUWpu2EIO;+&a2DLPE0?*YJED9=Re!a`YxRi&B7^v!2%96JkGH zpUVF|xz=iQcy0AzQO>P?NiN0_3(dN(x~EwB4YfRCtR05PO@|FMR><#xKSFP+DRNDr z{hCjldC`+D9f#VlCA}&fxy4=6?M0mY(+>{d-Nn(}Ox@gB3p!14Z)Ab1al3 zT~$5rQ@8T~Yo-oU^vh`#{RzY`V!F=}tgN%+lkWMwoI}nHoTatRzz|datX$Ig)m-p6 z5OZ-oBI36x$?!Rtq@WoN?nuusirg=oi;r1?IypppXFJw#N(PXRmX4GN;!ww~)rrKj z{DRtDI>+6~9cFg7WLc2@*vu3$(B0R!$WkPON0V03A}^#02IFRyazW_52ozL=7)WevP= z;p(8K%{0Clegi1N#Q6P++umo{xno^DMSkAn!dRPF`6e~0Id87`JOe7CPvAxj1pd|m zmrM3O$^O)RZB(wv1%R9AnW21IOFVf;qywoAvC}UqwkMiB+Gm_?Cj5W(`; zSs)*0eGM;se%9#Uom=|b#6)lJzdOB)a)F`x86zyJX_kh8iQ_3DYYl5r4n|xH4b9sm zr0ItNPs9wwYKtQuOA{Vml+vQ_u_Y-Hwa4P&&N(&NFBU6tY>%jAw)%7dcKlV+JAof3 zx?Yu*FtF!gj+($oEiEmbyufct66-}<;uFuQ9=$%LSB!KvG7?+D3)YS7 zTVA5Qc|=6_#{^D80&2CjPXwe6hdvrlC-r7bt59(HnGfHq;R6F5y$_W2V|1+vrL8Za ziGPzHF9CRPI-l@cq>qB$x&D=TliVA4anRK7jB4a@^5+P=Xv;hK2vlK9$KrfF(Gj-> zJcfjq_?>OA|5V)?Z@4j=)>lR z4zKXgkA$M~KN2cJgUiS4v(<5or5pI^V?He{^4hAANSBMbqDyWVo*;25_!CTJvN7=G z2evaPyAQUtm_NYC<(;l_&56zhi{M717uL*Qj za8@q|xf{(rt{80ewD+AHbU>Cg0(+vNL`lAf2iW>cLXeausS97$(Sm5z}+PLfcn-*m0w^4;(k044?&o-ia!WySf8!7HdTld|Mpj))K zPJ5`7)##MoalSe>J#yt8V09ZY9dHA77|V>UP5WG=KV4poyLUF?rqkBVokA9+WEWq; zZWsCHe0=7KprMS+?qJ>Hn~}LTtNFgJpZ0`b9#s~Il9me$@Jl2+c{6M~4E-ccHW=$| z^~^Z|W{3IoafGK|{%w$zr8{@1^ZU7xc_f7TDCWt=Bpml7Y|2Nb8SrZ_KP+7?Q#kVe z?qp%Y(oyEYDn^~Y?){%1&WUOYQX>2{sb;;0lociPbGFnxF5Hdi`8EH^+K%+)d1sM> zoL1Gd3zwYp#Z5%X`NA5a1bIQB7UGHQ-4|E=&=?mWOHLiG>$VC_DgLmHimM#`nXJ2R zcdwK??~_-v+r2;g449@!b8Za_i5}ym_~N4FR1UFm;GTER&~lo-*UnsJD&4o@92f5L zF%8&8$RthJ`Punc$%a9QbJyMzrLs#J@PI*8DOO6TZY$h z%3|8D7Lww+-lq#oVe432JRQ75W=mjZKmgmr5-Jyi`PwP|WDqXUTk_|V)ogb+FO8?! zjfdtj7jhbeUV(DQaloU1!wyZJXARbR@=kXZ0aD+bW&$`2WHo&qN#)f4J{|ds3-$VhMUbFcDoBp(TOjy5)3v`FYq5W`5Q0gC6W^h?OCq_f%)6y2mYYunGOzr zW#o|zN&}i%+W3m{o<1jY_`Q8N_IQ%bR9mHlxWj{uXOnK}*Vw5Zzf4j2ZsquSSDRjR z3}ZjbWyS~Xdgu6$aL#7Gzm08*xj84!pRQl_>S~We)K|nE`6nD__rTX8?XDXKA4r zqje*td|A0-Cz8)%6rIv}5&-qHZu%k;CG#5h^Qnt7CEyjJ-!~!OZ$!nxcF#m_t=W0N zCnJb=0Upi+nO|;1N84raOhbkEHO>V$bgquOODp$2YzL<$p0c?bd1L^QmM?}=Jkx7`>W@I zgu4R*(sR9gCW=>6oJCSyI<)jJxh)3&-J!YiF&#qNDR@7Yezp>G<$=0$^H{YtLlU`` zEXMGw5=gU+h~`{<@_=3Gu8JY$RgMtWI=_{>2}x!|23mBV$iYi<$!fG3q_N?7g3pDi zR04cG8LM8#OqJ3Z(o=GsR)jPgR(=@U~1D~hHVO&eRYWwl~CdGv!!HU zFb=+M_bt`?cV~BphD&gJ0G?_iK*6Pkd(MrizSMk(2hOX-I&q7y9Jtd*aG|QalJ0A{ z#}ZIX$}}hj-e!7no1+B1?>)6c>;RFDO{qauTu+slNi1|-7v93E(;ztz_&{EDhEgqKA23j9Z&i)jpKkssBi;BHCnO_k})UH#Pfc7WxStdJ|~mu#_+mAhmelLm!Tmq)T2>=^_>XE?>N!8*GCi<+g zX)N7`e|IE(MEO0ktBjK=Ssh}x1+9+<7yjUJk7nWMlq4_ogfmUdKcTL+r5AG(H9e=WR z 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 z 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

sV==hQM7clYoMhSwk^G{q!J&*M>jSNsf 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

-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

1CL7PGYZJvHYVzg^`bSm?r1I82NH2~m{J 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

P->r304RkogW*}fo*eYJdV7#T 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


jLMw;7 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®@0v&;M##dF`qo#6owa7irX8?1Du4!ED1bk|P+N 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
M9sOpA( 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

)37LO-aUooqJ+ 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

rX;9VudF%XD8x`9_n8s7OGvhcpO)87 z?%dXW3$Ydm0)guX((C?`ZI>fhqsXWVG*0EgP)+hN7p?RnIic4aP`k!JKglDF^|#GQ z@Q07DRQ~R_o#+jUf;Ibv&J=A<-eqh!7+d1oEzh!irLy3N6Yj-Z=Wm=eG#D99=hLeF6OfohO+kjZokteM7~>#Sc{Gu zmxnwI_c-E%CUJ2lf$cS;_0|?PBdg4}zQt4rfvyQE?-g;=39n!I$%ipeEI`An$ukS=f_WGk6_W^E$bXwt$_^;i$&8 z#a4*Ll+b{@g^X}t2A&1K>rfaOOGDY*2qnKZj=FYiF)1m@At!>ZoYcpx;j#*r9UWU( z-0E&h1}MbUf4+gyZMN^-+}Z1O7$>_M%X!qY&FhyqK6d{VVy0ev^o3o{ z1f3g4o}B;X3t4e|te%NLyC3S*n%3$J`{=ED&ak;h1N<;%;5OSKjD&nrw8@o77h(hW7~Rnaj0iaUi+xmM!t~@ zfEsi7$8X=V#^2e&iJJChP)7-=_SRlqQyZ&%2doF&u_ zARvc2WQE2SjSh@BmNoq4$osoY{8D5*-DGvD1W{_GJG}b1WsQ+liCO6CgMgy81BE{& z;8r1%DCV^md*wov>^<*-2ORlR zIXA+cv+sgbH>HZ-+A-79SMwU2Dch;~UVPs7=7hkqy1dU< z?^Wxt(?sjMYFBCxXVD4zyJMuoMYf)Hv#mSf@D_)bvsaI9<42YYG#Y`+QTp2hR!2?e z^_lNZ3*&R_>YD{&@ia9CrMXjGu_Yz7y$(R(7Fcm(iGedgx%BY79&DW()Q zmNeQvaPz+h3N1UvUftzTtt=%K|Lll&E71VT8AP)AVcdH*JlK=Xugt$iPCzuxE)9nH zWn9YxC?c-6a#2AOZpL2F165CC=~)oAZEKmMV{e?T-qwgd_X!@HFS{yY{?D$X|Bs>H z{}7F*G|}@F`x?x0Pb8Sy6`ZN~^4~@ z1INAwH9{^brmt~=W+puCB)lq3g}Y3%4zT`LG~5&IbR^<2NpIVXwH%Lj&ea_+G1VY?=J_snD)>f=DoYK@9*A7 zJ8@_`2g-#gZTsK6#R{}5F;&%_&5#abk1}&b%uLUJOKJCi%Nok+>YI)$uJii)n3xE> z^4E%x6i5fwd*Q3au(oE&**eL+{oDMosLJK&R9>KCT2-Z~shLAemHl;EuBpVzF8SP$Ea!in2YB}3 zS6hBc7=2y19PEihM%hOO*4O7m$r_AW^(ANKE^-#$)+gd!PU z>azJv6#l3Sy5eVi_PyoN8sfd4r9ojiB8KU!f7xu2Q-{RPBe?Q>$ zNWlv=d-b?6XQ)k+2HghKD$;Y)bDgED@_zZ}FAq(Hx`5mqgw*(hfJk9Nqw@{{9iCH6 z6P$-6CAAw?Rq1*f7!+pLi?3Z?)oHc_W*m_FZ1W0v9Bd`a#oHR9#t!|dtTs3tAJzi` znny$_Q~Mmh=inNnW*>Rp`>x@lR|(V#BKnH)UpdVAp5EEYY=^CUT2GndNduDu*shn& zBr}5k!{mp}Yxr@ne*PS%^-mb-d=Zx2w@;m`1X4)YVcC6x8_HSZz88`B*Y%52HZjS? z)S?K(&jCUzu6oa8?N3?uD3G`M^qO8)7f5DUD`K7D|768&bkDq{o7mntAb(M_*Ob(y z``5(1XDoQpx3;+moAr(sB6y|ht)L<{USvz)tyu1HvPs_LYyxkygo$)PxHxSA<~shE{nCI*yal z*K2KafG=+EY+p6Ru5x2ocC)xaZdn(gASiVf4V%-C;p0_WyM474QQkk4ZVkH-r&oU}CDSWVF^E`(qw$=5+tFWe1n4*>St zq=(@q`@v?BXnpC^^}B)B@?PxXMoGwUCmY^#GCfs7uNVR6LMSjy?2>AyYN02a-_1-6 z|GMm|B-`(grD@yJsPM%wa)3Xnj0L@bovuKM_o(x(Y@=QBWQu36YP{AW`VYaKeoY5- z(wzFOUdtK*XNvPJPzS|yLydrwQRxL;@1?-@lToP)Nc;VvU|z(f=6P_raM|VhfkAyf z^=;(DV4llXHg_TEA=ODfAx43XPkGvWuamKMc~bdC5xBif^xM$x6M@AX)l9_)&kT8W zBp)j?!Vk*WT!KFV4(OlARklph&FvS5s2}9H>vnC7S0*B;u_Z@LWm9US3EJ}-rG#&E z>jp;cB<7agHjTXtC|cF?o^Yu)PK$O#|9fC4$G-5K*4s$pOvPz{$2<{d*u8RAIcqPa z_1F5N!-i3txP|YvI{*oQ(WI77aM=E+)K!{KFJ(;wO0W8_x$=fS_Cmxx(8b~3gPLuF z1gV9A$;3wj#7JfM+>3^mwZxfer_*{{A&~nABj)FqZ&W-odw*!G3vk>9_(StjY#59c zfaF+&jP6qP1pa`?&EOt%VzZJp2*%blP#;=#(~y0>7QY_;d^wflLuj@@b^K^J~3OGi)qR+a8rW1FZCOe=0G&~`v=6=0eFuzJ1IiAd@!Ei?UIb}j$mi80! zjf5e~bl}0`ezC|tGheA`gTW9eR_*ymZZjV!;I_C*?v^{;-@@gllWgL#9eYjN$kMbA z_P~}(8(F4km$+LDm(8)~*rvPKr|`YC$NQkI4h|L5nnxBKf$sN1-}=w;H6h;mXqGgQ z?W88xrh_5^`CcnB3g7o^T`XaZ9#d?$s>(9kh%yOxpd?9Fi4%wu0?~WjK`MC=d)qu0 zH|Vcd(}dACHJ{$my|&D~ybZ=p*po^09Jd*0-^0-mZK^Kgly)XlN%1iid|GF$awjTL zyY(laif z9FAf>K*=@QHSf9o@M7OjKlxp_vHqEr|L5o+ zQGs1;k}o8BMR0f6rp{nKP2|U3r2=j}#g8C(f_7T|&~UTfl_{q=@Ag6QzQ$77w6?Vp z!mMwaWct1eVbJq7YUg)B^KP*X{p;H+Pt|JzK_Bycy7^i|w1D4m#Y1~!3qOObb>x@S z`p5k<5~=E#J~jRf#pn5v@)lyiQnCd#VQS1X=`(`TM^x8SJie*k2tqh zG78k{60M8M>9{zBx1|Wi1&PmMQa!Ic4M`IW%^%yfrU{R(+Nm=|38xs@+7x%I686E8 znAZx(m^lJ%@ySV@y5-G&g2ZH5QXjr9|7>)#8)2LWn)U)^SQ^8})oh#(RlxD+ka92iKY)B?Zeox80tWus`1Y7?WiFgn70~SBJ2qcdg zo&^{pI7PK0!_h1I-j0_gq~en-lV1J%c4q5o2-8N@v{suNPnWN5(a9h-RH}Ah>r(Za zch1iv$>%lOW_sB(XR>|5P|K=Q4%4`}{zge02=g$%tYeYqr$fp}efw32>PzPD5RJ7HH1t#vne+PPFATE#Z<{%gJnKv4G7)yO zRbhB!IsU#n>i(Te?Hh0J3+n9_(0**%%mDx)3NS*JgF020r7|^*p?RB)jaqsb1^IQ8w!C4S{>MSE$Pq|E3-Ibr1BwKfEJ#JbX_)SaJ>=;spibJ*_AJ z#wHcqKCtqTdmpaa;Y?}zW3xlXyr@XXw>HQ1^C}V-98avZDMHzEr>Q>f`Q_FOX zHMr7CZfV(j`D9$G!MO>O(=@WR#I?qZJlV!%Xm_`97hHnk;zFZ6z4talTDjw>mKPt! zwl+F-FeL({Z6c75KOZzqW_}qWvj@5kxRwApd(=T4(a^NOnwD3ZX>>Qk4Xcg32bZeV zvbjXo`0w2I7trZeA{?07eJUoNwo5eOgF>z~$9P!FYF9BN^k;bTtqEun_y~D~m;=C) znOu59!uCeTAFsrG_?dV3Ne`!4?yV7QIo*oRX70Kulb*T40EF6IzY5|9g|B6>DNVU&OL6F<(wMxkMM* zeIkJR`oQ!=<<8Rh6pHO=P8F}&{>+!i(dN{|UtRYdNqZZyB*%Ql;R~;ea8Zu*W#E|l zG@B?%Yf&dnQAoS-B{|ESABu@FF7Zh_>}DNI)jf*m-!TQH?Rp*ZK^j$eJ+IcHLzTD0 zHM;dx0HytiPx4S*wZnL$CC}Ko++9t95X|?13&eNfCCbN1}lYG>j-naMDwp;uI+W(mhl{7xZTleEp zsw9_V6&~0YJl8EdIhMqUQ)C@tv&~XokMP<1ZAlB)c7x3sJCx`L_rK0@U$sw+II9lQ zN)ODpBCWV0Ox8GK5pmW}h>u7e`2ybwO`hJz?JZU#z;`-OH8CkeFflT{7b4|fNV-vJ z#}(go6WkDe0bq4Yij%A=I}fOkSS`>Y+wMka#iUmG2}f)l*X9))?$UV|T9D}Td$J2B zHBnE|;sUorQa&$Otq=nypLG@C{7ROtO6E{-B6+4wksMaD8uqX%M~v}dJT)1evcAmD zY|lAya!L_b^S(F9guVVa0wi?3HdL4tTja5?y)L{{n{V-X^ZoOJNVqwTT`(-2I6mG3#AC5LfeeHeoTDWA??%j|v$?Ni5zrPiO%-Y+w5- zyKY7^ftu~KTV(S@y^GR7~%Iiy)=OFnG569btOT+MysV6lBwddJXPN$}6hncjE z!Myt3s>5`%zP(e|+A&W3rW0B4av#qTX%)S|E*%reCcEpnl$G1$lfWZ@ULdPs<#V`4 zEi&Mg7+o$>Yk>{{p0l65>uAWKQ2ZpB9O;*%5|ni)=ryRd#qrv{gdInuu$WS;)sse| zb>Gn3VMqBz87rg*APij3BjxSv8*Ih<0w3`!|HPX)Rd!&cUYfbYwjE;>y({+H4@;M> zkBNvLMrWY~Jh}UzF2CJuUkUhdfWsZ~je2ag(uWqW*e&6CY@zen@mm1wD61fyeb)R! ziK$y?0Z9rR;8a4Xx3e)tu4d|Hz`L!y%3#j)7qxY#J@ad=t_skkqNR{j?|X&hBmrI_ zLqmhdFakx?vNa}+IrYZ2PK<|)Rif2IDhagLF}#u(m0BG+OIoqP)P;3!Y_%f#0> z@d4}enL}m{G*uR^dO?@BEg@R(tD-B8B7Y2dyPsX4UMENEtW>t9EU<>(z?Mp^4&szJ z7s@0|6peikL0o5R9ZMIJshWr1I?Og^3(Vpw%4G643=fr=n8sqlLQWeca==xc>fFz3 zzI4VlzufB+N3$ZUb48-Ur!;WhV2&yukop!)i5XS?0vj90HqAl0k5Z1tk9=(Ijg}~` zl9HUcpf!K5^b>|krZ%PA#`9zyrlm%%Z|MZ^#uKZ&5DcQe(Wfo%@jxGl%OBByl(Twe zP)erN!(#LU`V0R(2tU0o;hP(y%|sNQG!48erMS~7#hsjG)d!ZWesE>@D=@aX*JY23;BT({helkE)HI z^GI^71}+wU^ZqsDs%gDRLC_Z9GfQ*ZTVFD?bi9-6w4kr=i5MQ8Y$e+q8E!>*>n^sm zxt`XmQqF9cj4%|Is~(SkQ`-BH%O`GyO8{1-hl|tIcv>$sr9`z5G0!P|J=`*UrNW^% z+=mnjatgrN7@~?-vt&?ENrUVLsH<}dt<)vEdnAqc>fP~BMT0iodx`Xx)^?XlY|QO0 zy4M3Kc01##7RIUy%CO3ebfq7Zm43KlWDh4NH}@$Fix8ofj1vkqCe z?%?mx$NIq}ca`U72Qm(`rKs2((s_4s`)R!!ST*hNZ6gwID5VNj%xbRQ{#M_?J>SQ* zTYRGDQ?|%byh%X0a5Pp|)4ql_D!7(mWvI!~3yas*DjgFWf(tT7k{YPx3}F!`ubn?~ zB?{DP-4J>t2Xd;fws0kN>AQM*@@ntq*pgWHka9V#ObpvBSkBs}Ur_@)uCf!6n6j4E z>|$;1Ye{rE`{QFg`z$Rghll5(5x|E>^J*0moK}yyx);8%Pna}#YIG(k#w$}RHOf#T zR@CmwY%8zI)cJFgVxlK=D-OIxJ;&Vvk_a>{E5!hir+tL0JaqeHdjH=8)`yoV31jYq zEbT7GkU3Iv&4KT^96O};C&gXn`kuQI$FD~O26^VepC}rw*>f{oS$&@+MGH3jekdr9 zW2e9Ia*V`t0|f3I03<@9}`S0NeC? z9LMdauaMbIgANJHsRy7Hq_*zC;Y^mlH+O5JuCDjgwLfjXxpH&f$0?cVwnO6WPal(M zCHW&TBUlr-Dr2nEWM%SqjoZ^-AJA5E^QNt$4pa+S#NOc0ar!NXXa+sn)`Ee);jX-y`T4a4gI0%Z|d$1w?}0{d&g-#fAMc0 z`kw5YIV>e|W8xMJdsdF4=Z!wu>6^ad!Vtr3bw?;JG4;fy|XHPJ4YZa)koO`&m zu8}w#1Piqt47`8+5PTY^6Y*EZ&Byxa5e6anW{oB8KpRafT*uNxkX~ za@_TQP+RmZsx@y&&P2lvb5<+^CPJc4f7S5+wpOt(pot2 zmGUlax}9zrxED*FrBVMQ&DZRvqslxg{kHT&cL?HcDz`aNAy*`>{yQzxUQctP;F!N& zRt!7sIweZ1iX{nJd?1EWj*FFAC3s)U2VgtFH?}Y+ZT32E%}!;r9L^=~&)E-N00UV7oemOz6MzlXi%3kNF3azT;U)T^ACA^|)$7Kes3>TNq;pv{_)N{~F^u}E^ zN@MH^YjYYJBrvc$_x z-kMgLfwpvrWq*;&&qVf?$bgZ`$#6e-a2v;dYC)&;f;WW7uXR~LR`?dx?*t*Nl#E{G zTrK?j?;3jL5Ma5X3TQ4%>g-%Ml@-Va?#NIjyGK5hSmiDJDo)w2F>2o%DEpVHv)s>n z`TWNSxK=lnwuAqT+-t%QB;jJV{2{4M)*=ze6lDgfyw|hCAWqmu5lG9f_<#xghXY8*ItM4<^{-VNrH*x6YVf$&{t?s>4J&nfCtHkS}jxNHH zZ)~)Ts?Sp>#-QPjzOKt%hRW1RxzA(ob=)7S!zAQ(1C%$M^PrU2AOk%*so!UqepEn9 z!mZ~9_R=}~;QGjfNb>4ofIz(8xK6^xpQbL39XsGYe?E|!ZR06Hp(PSm`DKLYx7SBg zcombDa_!nek7Z<1vZ@fHA4uPBsx$n}s?MVXmm^_n3pWS*C=HMYVjJYtXs`l0`!Zz# zP4?CTtfpaMtuVOzaS5|Rj2mws$)DzYW9yk}e+l_Wl(j!`Z50{{*6Le-O{M-J+fA4m zk)MXo?(V8p*`@j-CES0{;uB``11Tep4XZ`U(&;LNSbeHU!Q?=INR7`Z*^VA%C1S0R z7TQ43gcuF)4%lR#BB zS1TzL!_`=zhb_N+*@>y}N7qS)J&aTlYjg7U1RB-jnM8e+Ix$Z~Gw{sZC5`a|QLP>EqjeWfAR zBl@EV{JCmb=9>^^mqvq2kE|g=I;qFRn0~`;`V%)N9os?ez@BVwzj7d^WLOA#+KZai zv{s#}vZ{(IH!$($0skGH?VZhrSqxtBAEQ*SzMp6;Qy?dbw5tbyRY*28ZFuzxH>Lf2 ze`+Xd(!QL|cZL&_-;W{T_kT`LczZLQAh+5AyU=;(kUkWTS2Tlisxtj3vasv*aHWH{ z+A710>bA>~6E7cr2U3>4uTrEMGFNZoL8>1vhlxnfoH<`3aWek6%yF-0_C4lXk^+o? zS09zgXQ=ptgsu=&5%C3m&xF(;0Sp7VLqJU>8oZ*Rhhl;5V}nut#t_)9u-$4|C+74| zBOT`v18&t$T%EA#bQ@zsSA4tzH@mm9C!JCc>qv_zb-eyhZeMqF>)M<0HY-kj z;Y)dUZfQF!MmydaH(n2N5A6GCr;eqprJbJ#T27+b>mHC)>NKb-809ovU#7ZC)?2iA z?QwFKGosXsa>((GGw3%FoLZz*Iy9iB#%}t&<^T)15iqz5+q%Xfr}*1fGGTnCp#jlk ze+nXr5_kFvMbv4iX#et9ub7W2oTR`?D3zU|0$!7z;JFIh_@M<$I)ui*i6WB+WmJ^{ zGjD%(@lE-b7}(#*IC;sd6&`Un^NZCMAJ5BE$2gPN?T+CjpTo)f@GG5h(=WiW zF}Yr)_|P1(M;V7>{yp1H$@W}Y9{W>%Hj5THH-86_k_E{g(?@Q=B~H&(q~PyFN#<`3 zeE#q)NV*;P{EkU)_?`AtOPRI78%4@r`t{hk7IT*4*2qVq6d7GZ*{@g<4G*`J zijR_B^Ly0Fd#Jy~- z--7H|@@J0pxdro|l#j%gRV0L34q1`c2kp?jnT&2fWcDXzqBGc!2*Ee2m}fWK^!)5$)oxQ+fDnSSH6n+VIg)4uAYF{ZM)%6PR(V*vKM%W*#JHBlN{leHDFBa)wT@~d8MiVU zL0`(BZcr(~;y)fdUJH?#icWb-nI`%rwQL9U_}?PKzU@jU83e!R_{7n)Fc~sEl zqJWi=WblJa&~cL`OUnsdG(B zToNb(xCwW^;zz5oEU7Wp!kY~T5d`63dKJsPXEU!|XbYr%zC}Dv@uRU~3C$`i%N(JO z9kg^wE_n?a zRb`V?zqPtu{?r?p?hN-gerLAE`W40sh2edV(kQ+DPy&9TtbDtie5Gupc6fQcI6`Aa zbc>4@&nO;JP)Yu9K+h!lT2C}Ls;T3AAsK6jOo3GLiTUa|2(@U$r^*PLd*Sd;(h*rt zGBA1{2jYv=eC>t0ESe5{CQk|1t!4VxK`Qw6hPxWoGXAkeECq>oh8g%AEl2pQn<}gwT>S>Xn4KY68f3-}%pSA0eacw_ngZmPJ265A$TeBQ zZf_P(hVnG5%p$T<*e$%=2N^l&XwB6EN1qcL!P3chQB8r&w_l!qZ8d&&{606#YlN?g z>EpWLDNX{825dWOhlM6Qr;|=^^(hObfi-o?Sc-sB_cp(TBVMQ7$8ZZ)>aUxdS5W^H zpRD60I%}c-9vO|e#5Ir+05LTU($nK7QR{PzdJK5)ufE&+{q#1xnB0xp%>V0ECsP(Z zRY~uX8Z1)1OSF@s)R>%jPWW#wq41LrHNJ3dhT+@S_yT^1AI%S_;|zFf&!CMic7V#P z=6z0ZQNZz(12^IeFUz)XCF}w;pEWFWVnWkfX2AJS>qe&Rd1BHwp{vebdD!59v0>8P zRdF@q@XvZH@K%{vlFM|ZdZ9l*O)X9M5b^Aag0y%``(1{g3JhGgjf!W@Cszd_FHpzguDtdbUUK#6zdHDM2-{YHd2^w zs#1DbEz01(N4y@JdGeN9aT0$hJuaHB&Z`;@RZ*Xk&t!nMv1k3z zzLC}8Fcr%zu!nZC-VeuX{^nDCy6RcO|Dz)u~bX<_3JC-o2(Fv4{E^l-o(|j-u z_A8o{E}$pN?RfmHPxi9~YwyK-r#xET2kM@gnT|O+mj7y#$|#Zyc{?I#U6)=&PsA0a z@t1@t!Eikkflec2)X@&p361upNm7a=I$N2d08aW7sJTVEq$+!DNrJn8BU_$MriIfz3?P!1rY`?r&(s)|Ww!glR zAtO0$y@cfeeqrCVJ!qS$eo9M_6QC4J8E-0H$MA~YDqixW7vzy5Was77hriSV+Y;ZK zLA^c7N|{pZJ?gLi=jP?-T(x(bpligrvHfsXdNS=vd4$^JGGBrkPX`WAWm=;262 zz?NnGjJ|pEXYkwaQyeqIrb=A@1V2H@&OY7LoQD36)&Y;T9?&$MO`0Kl((Y;+=^8pT z?)U5O`<4)kBbBPtN67LLBOm9PLEk0X$-XwK2acneN`V*|*bar%`tyN*)hY67T2dR z0(~RBx(Mt*-`*vb3V@rO2J+go`L5h*+mw@8ApF3{v|aciRCDBdJzP1ElaNYDfUr;R zo+Xgoeys?!0xN5&+CHnrx!hRuku}!$ew{h*{Vc;%`Xk^#i3~@wHvV<%LG9eDxw4F+KWjOGQ!j zV3E6Yy3Jw#&ML;A8u^o3yuu1hE?E3?2OWo~jMY4g`6MQ(Ta_llb5#54jVuEm3F$jr zADN1nxPWXvzEkfqzV;hd-C3}3wVT6m!x1RDes(q3So8P$|~wx6j$@SP%7dHvx- z6&9kPNqII&iCKwRILKq=tY4?>?go@KqDosTOFF!A*jkYzSr%miPJr@eC%x3bpti&p z?uX*XO|2mR-*h2fcYy?n9(eRF73Byw-4+5~U*_l!%t)aPcdirz3m6kkPX}(MVh?V7 zEZ(;EhN{yUPd`Y60Cyr_k3#>zSUe3e&8JINmAdf$5lju=gGyXY-yOs5DWB0i0$#bGaHwT43XqAPQE zE>vBTG&tpMmUi3j?F(3u@1ahr^V|B@q~U|pnKCHjTi1D!7+A%8d)BSZ6b@@rXVezT zvOB#^!c{o0%|K{kT>0gfB)@$me0#IiZu7#%BPo6e05XhA`tOk=eku0%l2J%obF_2& z!f4;Z)pRiFegz=)R=L8tb75uj7ef#Aujb9)>Or1XJO@Ywj0v~qxH}QRvcinMhv;*u zFiNR}el_j?nj~rgkaiW<_%vNaSF=dFw5c{UtEd-uHkte>#*)Kyf0)x_zA9|-8gujS zi^S@Gk7hCU!E3$Q!5bsmlD%PjZ3-!FP3(hnrj)I5@VTo1ijqu5^4NQUbs`y$<{D(HYz9obYuR@^;oV zH8>Z44*@tf{1EiLZwKTfK4Zab4cl4spB5YAScJaf2^S3yzZY1(hs8 z5u~g7*SIXvCZa}q55!#95$u3gQ3qDWl}4klJ3Q<=f!tT-#g0~z8(uxA&_AE|_Av;I zyUS#q@BNK-p7#7kT5J~XFH-fuXz`aWR0vfV8`s4uj+{z0iHldqd(V?n z*<6LtZ%8DUs;WxbOcdD_ALJSVMJEZo9TCK+ZgFF6uN~+^deih_)AAX^v-P;w728YN z$>)KI6LKXcF|SS!1T>N@jd#sHdHNfPD1$!ee)2Kw+&bb5bW(z)>HZTgGc zQegK@(v;c80ev7=)U`IoYCh9S9=F_k)UMx zWN5a6xO2V2)GlpH{JtatR7nR6cQ@vjcvz#yIX{|xZwfPxhmFKnyAb!ME9#e?$6tUrg+;ROx-Q%62nv-)7pb=;$_FoL&r^I}sH;7G?Jmn$7*DUbRhR zq)Q8&wA#mGLRP;MzXozZU8c^p*uU%j>8)`ve>6iYW1Kc@15)Uv?l)0>^?pW#M*b=8 zRSzipXOWhcdo0fZ0H_@(Fr%kt&`f7Z*`pz2%Sz!))~h%=`*0A!wAL2;J2iIDg)gI) z)AVW!dGS2o{8zyd{c8k{8d-TE*w0m|w`2xY`%m)u^JSIT0X_5QRak*2N7o8f`8$I; zvpWiF)Q&Ja8HZAmx2T?XSSpq;$4ih-GHwI5U!USYHoYuePQTH1qYceFI@B@Ap1GI1 zt+Fq$C>0?w>ER*n|Mjl7T9%sQ!`mH1DX5CMyNAbEX2isYCwJtx{q{`knM;X^T7XU( zuL)(gSATEgy_Q~`lG6VxLi`jemiYS6D2e25tCm;vOeqvc!X$a7%pWoDSLh8)0eE;{ z0Fjf6$=W6@vrY|n!J2_5W0It`aH&EsY`>K)%&2bKgc{<}{sh}F?(A{qWaN0)8UJb8 zOj~o>Q*ALod+PKeSo#7OtjOB&6B~fM8wr23Al8;v9u*Pp`rN#CCTvk>x_Mo{SE`Be zI>VV9&&k9ZLe*XA@Ww|*nn_?@;T3;qinP{k4CK&UlaBgZ=0orEan)tvvqALR%MyGy=@lC zz-_)uHFsv^Cp45wvQ!(ebY#(L+FOWrk+}R4(M#AJchd`JLEjX(xJ~??Uu@tuHnuD2 z*h&2p1<>@AK<<8ur*BD$&$J5sNl3gUS+`VU}uVq7K?T-I5M3Vn=k0+zM^`tCI zjg6H4Fu}!C6HFk^mq9lUCSI!f(i&&HGwHgVv%?)VkG;UCqV-tPhMX36(QRD3d7h^f zB%Ymf;eg(|od{>6-}3g$Rt>0(92M;xDiw<(eMkDwe|TehemPk~IJYu(C$-K;xt(dZ zz=N*wGr;u2fHWqmj>2^p;AA7Zc805}M9L4E99p-ruyctG3=BpPTgKhSA9G{)d>7;$ zAQ5WKjxqtVAlY!~V3Xk5Tfd%+2Yv6}E_c&M0C8Z;Pr2v}_oO7(hOA38o?uGiVp4Kg zwqobN=ZPURTe@}z;??Hv?C1uxf&`*bASxWJ5jAFq>o zbGC)PW+w56Eqg7W^_#eV=2N>=v7L}$ICB_Zv(PQql0BY9nN zv)rTN(fZ%qtK;DZznZj;HFIzcpldkzJ_SQG8^o@$5}4%Pd${`Z=sHX`t*_mqW zkB(O5tJl)es^`ri$gOa?QH8ODf$V2u+B=(fnQZR!9Y5z2tDN90sgr9Je`4o*jGiZ| zaE~3?J}j7??M%a}eM%sn*sRGMF=H=rQQw8+nHQSrj)d|^tD1OS7<;%VP@Q+QxbxbnyjbSRBxYG80hAaW1HH$@@bTMsS+ewM_ zU0bX+(J&|5D4zB}4!y&1IMZC%IwKgF5ZRSQy%u`$G_hSLx6Q_z20mvL) z!d<9Y=9g9o6(s{zdE7}hJclKk!(H4CuROCan&)Zqr)O!5OJ9Q@^$A_T$zC`jQ$%iTT9m8z#R{B8 zPm~Q+F>NZVMl-V|HD&qca@~yTF78M69$}Eb-f6sq2e<$Id$5rSHBCu*Idfj}kLJ33 z?F5CA8pRI-OcUEWhLW67s^)bq6MoTvzHry=N4hN3d%n-Tw-_2_Zu-N5kStOSe$-u*mT?=-hN5wHe)}AYj*Q z0y6NryKl{4G%i-lJSH3GN7U{OZWcHsx+PSXD}lro0*t2<5+~A}sJg#C0}H;%fPLU>OxP88~Z!bA3)!wpx~%1hKWXt|VoKL@omnDnzR12i&^KZR20r7 z`#p1TKzmQ|;ZRNqz*Jm+WfoP$F{QnLobNQy^IbtKsxxQ%E$2Pf&aoY(;K1y_zn%h1 zjE%ZkI&_@(g3LI+nUYYX~7 zMpeV3NzHx^%Fgny-Y07YmMlc*LbXDd`We6d`1z}F`u86?f21&*Qz-{+WThG; z5qavs?W*~)*AyC$^fmI?lt&oF1l2mW`LEUCj*u~Mhd^>#rqgP`f#R!EwJvD^*c>w& z=c=l+4)%PC@Gfo{anU}+Mlg$PbdrZUDGX07ON+J}^}{;|*XsA^Fh|MZALsS>2yr?mq2m&qI0}Pp)7E5;4KcEV@tj zb6R+AbzEqy_6kckQBHR6xZIM8rvZQYuq&b++eu2Fv|RmDF%aR@aiaj9zo>x3Mv>E5 z9?+1aMF`tT3DwD{Ms(G81wIu@`+wfbU6j+>EgPQ=`hS*dhPOw5&9Yxt(*FGmD_0&| z#!rL%n0qif>`@z&+wbeG*a&PvOuGYDQ+D?)1fmw2vDP}%5S@KL|Fv#Ovy!do;qK1`6ry- z$xDWnCx4mxAkYWGv&}!yDOa}qoSPY z^z~kRstci_l1Aq|UeQZmle*go)7mWrd$N0BkjC~AoqVb%=u|P;^}V-MRCT7mS{R__BfR_n#ThF1{prmQziq`CS#_u3y}*Tdp%tQ)FIB_ zb}UK@i&WLgvMbviuLx2fR1b)2FOkMS7WY>DOp@{I0KGcL{$59ma=rkD?U4F>{O!5^ zuDF14g}d!jrP-7MpfygXz+1Vl$PTXR*n{o~Y;`oSw1cw*sS3o57MYf>7^M=!?t2f z&v-!Jqc0%u=rgPu8hT|TWeXn4KTW>m^$XLp?NqFF7o;oL-`rpK;2*79_vK?g{=$w$ z^3Sh?s%qJ3zvN}{d6VQ684akmg1xZN)a+KH{jBwx3w~7__ zRZKvE5}q}3M-Ff1?>|zF2PzCHi#>#mr}%QH146aS)-LAosjsYYt^Vr1RR$@4Hmf0i zFJ52O=YS-VXB=-PJ9<1~gukrN%nb(7q&Yc25+q_WTdrS4O48X`YRCvb{HpN01wD+#bS3E?ycC(j`7e| zEkiW~1`=3qDrDB&EAG4$z!@>28}y!U9OC2k9_GBEb*dbW{i|rJ4%GQFLdArW+07=< zhdbx#=ZV+RoeaqyGWts5QW#y_)r$#aTUe(OSJEnvN`jmCmOuP#WQtc=QVRBsG*(C6 z&5t`#KM<~rgzy!A2=A*l?Q)bt^!~kNLQTpxUgDg9ILnCWH1XwHQC59Xhg_<~l~FB= z#i#N{;vxk^Hq3_+Hjj&kYQ9A|O#!=6qi*&SReTcvJu14`va?rIB`nec%J42;UqdhB zJ=8fg9~l~#t{Ip36FN_yp6##d~>#Zxp$+W0_(s~Y%}h!5#~}F;GZthG;)nW! zSP-s8MK-74=l2|^NM(Ei&hJC#ZiQ3{!o^x=;NPE>BY4m;XOrq0yiEhbu1-@;UgarS zK(`z}Pfl@ZYSZLXpeenBS%%2JO9f!vq#~Uw56sy{ z`isV%KQkMJ-kuQb11NB`V|Uz@P@DFfG*f>nhfxCfK3PTo?ajwzzi4KqJQDllt}&AV zJTwr8b8GdZag&;2z_QM)o~E!iq#Td0pLWS85Gz{SxfcKZ+mc6#RV)Hsw5)dG&96O8 z=1J(0qtlU+Z3r%rCW0Gkl(3Pel4kX+ekD4%ntWZeQoNuR8XA|tR1d_iez^O4x-nJg zise)VZn|k0)kL)gF}NcxAs{#ez)}O8HX6R8H~96%CDV7gRS zuZ85}1}+$M-91==KZQ9R<0%|f7OXQcA~U)<;=MZ{a=2cEFd}R!swn%h0O`4l>)_sQ z@8|UtrQv6Jtn0bf+VyCN=CGsI=2vmiY~Uusgk#MA@o{s5syV9Q!wT2sJySnI<&ZsKmPQ`gH8LME24&XN6}H;TffW`#mAO zURG3ltV_5!fYT|A)%}{LC@T`6Aa~5=ZwWi?$ddg`9E95?LMJ|?M4IM0^xv$&Ol(*L;jL^;miE^AJd5XZm)-u)wrJvi~8wB z4yn80Z?wkisXN2A&AW#wv!5iyvAI|Zv;A^izL*`ptT}oS)V9>yO46-F_^t)LO8a?a z9jPX=20iCm#8n+6@SS9Z2h%yZ#5Oq0PV2^aUU*08?^_p;hr(txMKyQ$D$?a5VR@L{ zzghbmx%-=0{s#~+(x|BXa54P%bRyC8cx6T^$!artswkcJ;)7`GC6uEP5-v^l35a!ri`;;;%v4}) zGR0>mBS}THpubna4?)ea_EMf5cWJWZ>ZYFBO|u_^M5U`ag!*S-^xT0+R zTH-=t0W|5>%r*grW_7lP0T4G!KXacPa@eX1HFMiY!^auXz7F{5r%_qy%IodxiDsIZxbbt+Qj&Fe(mTDn2EEq2ETk$q+ z{kgGrKcB(E9m6!)37vR_o(j?_2Jnn)2G3T}$G;M(g*dXN2E_h`%}_e6if;3h2LTn8b~sN4ovC5fi zGEvK4iUS{?5{=%@g2f%)S+RZtvk0xzJg-q){beZ_Qxo>!LhrS}0O#DU`MV2kgP9QU+Lf>aQ zbL(SM0Gi{i>8;e4oAL0UPiQ1w8vp)C7yaO4@#z1#{zh1jGzJ zd#GPnZa(+NLTdNdKmAXF14hQ4lNXxuiC(@D!;C+gGimbIUcc|it(Ew*+e?r)wN9GC zcuQ$TBkCi0@$1-|ce!*f}#D1hcP5nO-C{CoXc_Pvd^fuPm;Kp#0Mg@G)*$Emmqc z@ul41Ez{t84~|BGdZ>#u#RBm;6%Q(BE`cjHN5wb@@Z6)X|R}1+;>b%>ydN zMZW8ko+nO;f4!{p$O7di1iZ7N{&GRc zyQ8FEM8&>@1z&p$!H{AbSj|Zs&tE2z&(^V^-gh<;d6*Dm;~U45g){(2mPBG65kCJ^ zU*tT{h|9C@h>)d#j69i4DS?ly=F{^yf=}g|bU_$)3YM};0D!%-#N(>-Py_WkDcUPX zXc7TFGlkXt|4!Q5|JS6g_J2&;20=Yr05Q!-=lCcR9U-3^n~fM$CXj{WpcXVo#C39) z?%Lx^Ez3LUj4f!_7B|OgTJ)8a?48RJhBq%-H(q?i+7O$Gg4Dv|fyX5hXGJt;*U*%_ z!5F{h)*FkZscTOUg$3nlDch01W#TJv*}mtj0W(Q?8XC9jbD^Bm)?-6m0~ZO3^Qy_| zBj#P@%kxBm<|Il4kAMFH;wysMA^~pBN>{d21Jm+a-j|5!vTnXR-+PciR8CivpXT%O`s;SqLOY*1mxWmHZh}@xLYbe6j$?qL^v?yLQP#*< z>g_t4$eVHx;ft<@tyC7o_JjHze8#_syhJYgC(k}U9eQ{K)yYsI@v2tDWPi?EoS1dn zIJ(F(DTthAYNO^(muf^bO~Rw|KE6(dxJlFvV;NUEfxV@dkSbZmS&2mVSayxcQ9`K4 z9UVCdmKzaknO)WkH%G+5)=n=Ukd7(&J7vKHz;#qbn@C;N(b!|^*91hBm8Agv!=vA^ z--Yh^{3u;(hx6a{F)vmxKzSU{d-mQ3c|O4(p%&Qb&H!NLt!=6 zO=Q|;^Gz_=0&^3!aX#LGTVt4%lVNxcBXw;?Es50f4|}dB$TC=*m*eY&u<-8;D&}2F zPmMZE(QZ^;gbcNmS9(vOJOBGfYiJENsn=m}su))$fk|PLYWwJZs9QMwUU{MYU48%T z1fjY2W4D395Tm5`f(FmX+ifM1x@RKNi8(E_RBq2@>#MrLRC0s@2|b!N;=qG3Q$-xY z8xO!U0b8<8o@y`V;pKr{@HT1)rz}ohFS(m!BDhrn6d7}*aP_wwJNU0;xkNzhuY%cl zg@VarB^l8_f3>C4VJD7l|MvLJWldH!C|W?0z?<{+<0jOF4R+icwKuI*J3}H_PF%nh zlY5)sfeRG9*|r3Cf#M5!mGiU)CJ~vMUOq32n6PI3leh8TAP>Q9V@KJOSD)M@^{$cb zb#x0mhq}Ah@sZB#bmJ*L^|K3#`*!DEjuP!VdGUSeqTbS?L#{Ga=W4&7!L?UaP1MU$ z+J6NX&&um6{1%YuSU*^9e!XB6643xfJASChy#JZOOZuac_EY;F$BwuX$n|*sc*zO8 z9%Lez?z6Q{P^Se#X`}R%0~u&%gB3DG_W3x_-M^f$2!@&XYeJ&YPZFQIrExQQn2ndM z2FmRFbMzk74Cp(utn#WTP(0~SS`*lk@*~l7d!Zy@C1cwEjVyJnP;9|swV@wlcL2cH zH#tlF#Rxb@7hf0xKt3L2*!td@r?f9BW62=l7KUYB`_NkfxKW6KCb=QP;Q zs0_ZEvwK{z&|sxLzf}O&qz>HerxY$;v7b-V!*}=88#j3ed79)7LeQF(mkn-1FqDUi z1`D5V@>kNAh1zyR%V;sfM#we8qp+zJ(l}9HQ6d3)lE!yWYheC^U^VNt3OY;*(GLe? zrn@OgFjrpN--Pi? z@iDkBlQ-m3&~VyIr=)(x8~Qz!peDH2l_J6m|FNg?Gm(5XhRiCug$!7O^JTZ-<~KW~ z(z}dqc4I>TiIXZ2L9^osEj}C(glI-zQy)}H2&L<|#JZa5O`mFD*p2h$jU_*A#;R=9 zouFvHZKOT-TT=*m+x?(3Vop|?P;xy#=;0!8BgEPbcLe#A&?P$|4?VoO>{!FMu*S1$ zA|(vmNy#Z-mU4#&L6vl`IjF5L;^EH}rnV2+5&!RzbvR4h^|xS^SK(we zFdE46aO$$2;rtWsQH#E-ohVNB1sYym6TRrsauh%cyu#W~i}Fp6 z?wX<3s&w@HP_bT~*h#%oyf^c*Q@_w$1c5KZXd#4-GYk_eR!l`iyOvgCE@D=3Z{SF4 z^R3rTr7dUArns_V>{s4 zf;~0s)T2O|82UPAfR7N$gKJkX!2T!J;#0=D*7NkC{Lf!|rs*&9@g)11>^`PMrW*NQ ze%PZS`jnD$h)o433ojnni7dSbaP2&(_vuD*7IFePMbcZAs}yVSy!(_NC01jc3;(9J z>EgFyvN8{^=Z#23*L6UJWtB!cq z%v8*Q)8|aAB)9d0d&qx}e!g=*UO!&N*M((mz}37VOWEmuS4pW7_GmLa?|U1jqtSrd zfD?(Lit@ElD|F);IP6A~EOrX)$;w=r*?r)*0n{(>3HV{{*>iJhq*5e`$Li!FGjY{f3bU> z=qIOKd)=A}DTz~FK|e?h9=36hTzm`0-= zw2Cg@RB`k1NrNXI>YL8qx&ZIFDx@HqhZ_Gq(nKZPhMYevu^*#yTPvf?(r_OP7{&bi zi2EWYy5NAhDD_Rv4FFN11C2PJjR4bQxsk7*&1W?`SEmc5rdetAi36XB=QrG6q$=*!j*lUjZ9)|+);jxMWc@3B%Copv`u&wD$E+~Npx0It zHg2XUkjAbUBXWo$ja#g3brPH9W!aa7to4@k3tO`7AtLHG!5@En3wYS_J9I1lslj8k z^%^3Nif=E+HGTo4m$1w7X~(dT4!Du>^9-R03V#5&Ttwn1<6Nc(18$M|Z;Ccz8nG+= z$oZlU|2&3V$e|Hz-rt(86%GQNH=8+d=b3moQHYj`V=}}e2+C&CHuchYDMMH1SJC0B*z^ecCT-RCu%Y_L&0D`bt+eBAH8j00SWVb=A}fE%e}K z`Zx&)sPrDKyMK&5)vf7ZxncO(lwK%~j-vALpZW)ZZUmVHjwFbj#b^{|Xw}`lt-X=) z)y+!JNYy9CTNCYlUZE+k(Tq=@?wHUcoBAx|;J-&3(-twSoWcz~AduI5Qin!Tv}TMo z`Jca44}uD=vYkoqTog|r-7!w5dWji>G;y%rqD;|$k2-70+{)eQ%B9Meb#z(C)6x@} zaB?8`+AKKyMB?#1gExg+7C_NB^_WK_amQQHqHBx3nRX)$%oNmF&Y})(1HBrHsVggF z8lrf@yyE~+nVsi|HX>UTo2)9hI1(eK&4A^#NWg8^_p#x$JQQ-~F{S7C*=RLAvrg5;g0HablH^ z1O6+E0m?_XF!EoS?aWv_J!j(}z{uvA&+@R=S-G;zVH=bc-CVzXUp#U1zy-?DHEy6E zG;R-^vZcw%cpgLgZ7Yu3_;Y_cZdDqx&6k5;x*PQ-68rF*6e&!592%9SBniza<0Lj<~Lk5YvPLPqz# zuf53PoqqtmS{RpvZMJdt$^nbwfGME8^IKUn`^wN1t8`lQrYvfvT_P`(XTUq9kS@>Y zG&6IS_Pg}6m#PtR6ih=vxQq z5Qr&6&2oXSv~DrivWXVWbpq>g{Bfu9D|~8bB6q{dp!oY7LIL401G=ndRop5rstfru z&*lU@&GX(dW>W+)U3tIyA?iR*zU)oUrj-oM&VE2LIF_8sArt!@`UjmUI>we5K5VMT z-}00H9%Y-bwXx9BD*g8;^&A$5+WE042sr_VYtDT-0!&+Rs7zHZ-i=gnaRrBkB>yZha=T39Y9QFd8sMaroHUP( zTWTEenznYU!nQm{S-Zfy;nHck|0aa@9<8NB|F&Wos&C%wvKQQGQ{gW-A;ma?l)#ub zu{iwoPg|4X68OMU9 zhhPN=J=4gxaS36{0X@~-cbq|$#5r|f%`aFHUk$_0!O_3ZQeZ<|&a}5bErUaom6yt- znnnkERnniR?bE+4ll5UNJUWndp0eM!Le2);+rehE0VP|<5tG1@A1LO9|GA4C)L|Cy zQW2E2YTNa_fkaEMZF>r_lA$nKeiNq;Zzw8vfb zbOr(2c6Q4D;_fYj+6w!JO@449VD^ZygJEb&0(3 z(>ipF*$pB#T?3ij(cfuQ1= zv@_N3)?|Cnl{yQY>|tezDsri6Wjh-WeriUX*sSGP`j{%F_q=9N=>SXr7IB zUjetZZMPYJoMnySRc!+PES2{oe)45^Xsv~$WbAjj^XM19uZ;yQaozNgM3lRi8eo_cc+iA(XT2HLC4@4-KM*UrQMh(0nep^%;Ok$Zz2LxlbTvPDBHhYk#@Up!0K80nc5(PPMSB}RI;J%Zc7HsMd(srSMw}xGC{q2 znXX-5wFUC@^G2H@o+1nEPQLg=+l306ZduHo&GrfEkY*~F9*aafevo=VwG%#mBy#d@ zO@0u(5W&}RykBa|iJ)sQ zoUL=?d8w;SQ0NP5Y?WQ0s9##$a6aLPd;zF}?C^ke?i=o#gZgQm0W1d)lDRoIR#v=4 z2@y66E?WU*`2SF_6(~<_v0bVT!_oYEff-5sJ?<|AEZE_yJ^~w}W#f^Nv6%9r8njbu zwztuS)};Ak1ive!5zqi+hWdMq@J4HU&mXgXdtTB1*!au(7he1m3wa{HOwpd~G||dz z!P(b~*}uqw1=;=>-|-qe)Nf~J=2#Gt(vPZCHRccqiTEm9mSC)j(RaaI!ZnhdF|3Ct z+T$&?KF?a4k{38~c;IPUTR79Ma*zTj33P%AdUCN;?w@Ox>G=RU5xZE^`Kgs?I5>q2 zSIQ|E*#3Dum*a*l0ObOIy;kP~d;y7^aGWvv5M`u_Z z17lvx-RAU|QznAz7;=Jt@5CxOx}!WMCGO3>Kc=~s(Hg&#udk1J<_lETxzD*pTzfli zHXEk6gJ$T>67;jJrAz-LU?bb$`Kx}}axPwd5;mb>UwZ;j5{oy;olHWqqWb}JEs`)^ z8KJzVl0_nQdwGV)utkD}q44O(GJV$tN#5+!Y{w^dQQ0C?d@8G^W9fRa;fYGXJ>>ReUp3{%bpu%q>G}F`Y=wV%w#a-QR^< z%D&%ma?B>pF&X){%i{K0OP@kEKz}{86Bp5fs{U>XHvvkg?)ir3UewE*Yt6J zl%osdq)n}j`kV*yur)Doi^1<+;||+*N&1ZMdRJ$Xjjorx7Fc1O%;T=ID{mUfu@%Zr zv~7UYD8*jYBr1tRx4f@&(HGf?`jTEmsZASE z)^b+@!7KfD87EmeyafZs<^Yv@>)1AZruZJdS}C!*VyjOk6e-1~LWY8q*|kquo$put zruwP^0CxnJFRH&vEwx;E^J;Uh9FNd3d~H%;eyfesuOMRJM_;)y$JVXenQ#%893c-V8C`<^4_xSHb?sDzKJt6{skGGH*R8(I9iNjqTFA0~}r83`M_=j1j25 zgbuvf4=860z&|>e8jV*|TxkhiAE3+IDh!F2FwsAE?@vx?mJdh%w5N3(=zH}xT}+*& z$U3;K_^9_N4&0knX*bqKaV=ft_&yl22Td}znEoMl1}GPQ#k|B~WHF&TU?{EM-!mES zr)~Ru#b_i%TaZP1xGE*xOCEQuF%!xfKf@$EK=2Cv_Q+f~86e{D7O#A7tG2^$$rc?h z$b9&VA?BBQXIKM}Vb??Dqi7dm71`IPm1ZZsrc?~m^cZlOsj?#mylpOGvzzcpo)T;A zqgCyH9bW5#K788ws4)Kxg#4FC)tZOCTyddAV45Fqq8cnTl-2RP_$7O~=)9{kv;URe z^8gq4Z-KFs?vNT+c-}20&yi4QG0hGQ8HaG4d@WK^f-dtEfv%kmr7rgM49dm+er$BB zAkN9#=|P-_W*}CTOzWvv+Gz=VK6=f?`KP<}kUiSd=O34s_SRkruoQMaH(ETW_N>mR ze!`8-w7s&VKN*lxY}$~l_U?I9z{}-dc_MeZlGTAec~|bX_6%Of$s6lunI!-Eahyi7 z|6*p~$0yxP-HS;r-#w$?fN>x zJ<4sxS>~7*?w=A*rMmHkS?PN-XjJo7juj*wzbnX!L^Id!zWosL%gDdT`&_#2 z_Yo=)Wa~FnQq8sclTy@V!7lscovHQL^TQa+o>hjYf4I!>{d`l5m?xzdyR^l}>V!eRDARxk~=52D5o@A?$;) zq|E1E|G}Q? z$G@h)GZCBTtMqcc#1*<F97+#3!$JW)Il(Jc_ocMiMOZnf>8^HMpV{1s(h5>U zD3vuM5bL)*Ws4H9p+3!MCpxOX#;htleC8@j;59 z@?AEq-F}6_vfSK~@%wqN6oB2mm~T(iR^=6QlZj>P^1Eo{&wX=h)0g$_fQ?B80A>3U zrR~GZ7SMYaxKc4cU~V2>5LIlSrZd{Z8H;UYNP%E{6eWWVyRfFEsX;Pr``%GL5K9*# z7=Y@t5kE}sal^ev`iK49Po>HIh*_vPNqo7}T&7ok*j3BLzAEg}M;qw7qdWtPCkzF) z!}BMcUU;z|o&-%he)l@)gKdW?orD1%glecu`)~_6Y;y3tdGe0>r->OH#vgFmUHQg! z>bPK`ch&X&F%_U)GsU%IE#tEC>9azF6{hLR1^sp&r|;=RYai)!xompoTKZ7uT$rmvg`zOajjhSV~E-@CY>h)5qt@^WwTXUnVT}qRq&1tE*cL zsR3!>S-lYJ36e2bSmV%!d6aXuo`_Ks)LTt@Xsg7Es-A4fX%Vr(^-VbMqQ1gY!@te) z;J=GaO8vCh#mWbG(qrBJ?75IE*;cm8`?3zg({!KyLWk^#kHQT&UEn-efA{d<4E#0{ z$dQY}2u`<92W8N|_3}6VeFyuEjlz^%Npvp|vWM#*`h3PCnDgx@Tj!#BCaA4g;<82X zYAs;1@*`#J6DAk?@X;qaO!T#ZqK^Y<7?*R>v?h?Yr3L;o3m2khbNLN|T{`AJw^}+g zPd6Ke>ExfPO?UuB<}~x{KaaiK_}#F~r{sR)L)Db1-5oc;yqQ>@9{7`#Uh5DIt^6_@m=QvM?y;yEqhQlW&XAvt>uV0@P>pm9$>5kg98 zv6{yWcXg?)MGh?AI$vR7L$yG;CFZ$)p+``x$ds5y!K+WXki;F(GeZtQx}HOfuKRzfWCu z3OUp>*nn12T}&#sq$+PwomXwF%;sNon6(gP8LY?s&s@|Y%Nfgi9?Q*#mcVWUs7|`} z`|(E4zSkdpKZp2Uq%5Ax0ae`nBfa%)8DU+#KdVVbHI5@@Jz^;nMd+Vqe0bq&N$i+W zPgem|MJRhI-wx;mHLA`ULYUz(AQ99GM)2w(2Tolf>r9y$SuUjM6WcSz=>CIDykmiWkxt#R(K+EtLi989^$?9kIfMb< z#B68&6j-Quk@uDANp`=ZQo31Pzsk}0-rvp{FaJD8OZ-8SZIU#|;ct=jJ2Le-#AiB- z?d|-P^EWyC&=>}dnYksy9P*hC7}shL5*TP zpj2dr;G~nE=cN9SP*sJ9*F4n6srb)H*b}d{K=NMZ;iVm5k-jdsm4snfcQ`0Jb8uC= zHq~Oi?H^vmRl^c(fkybN(qKKt=v`6ekxyLQyuE_ZsHDF;1FsXkH$qA4&m2o=J1r3; z+WT516UmFJszpy+^2&xuLEpF6ns?aCM&6b+6L4m4A6d%WD_Qllfr?8~?;mk&=nyOL zQC=sn3_6iT@L$(Q<^RJA=2BAwEjVmwYCsEXUw3#wc;&iIM=1P@nGH1&@Y1~T+W^VP zE4$fh&itX@kn5M_J#5J#78Z0Ju2*{%Vi8XRTq@ix^8))2PZNC;bz-ZM%NAtRKm}tZG*;P$uV=vX=~N7<#SdSWV{7y4C97 z)osu65Z0B;XDbUO;dyy3%@vmQjy&-zbJiFmu?#)qD&W_Pv0G29syx(YEfJTm^J)dU zYfYbBoZh?Or&|vF`GU&{i$e9qnHI8_GFtqfY_l%1K2NGhdS@Cm2MTV;FPIXs&KP67~50W?fiqXNR`@S`R2!A{m-1&DxS5$QscJ0{AS(k-w{F-2gcQ{gfb51(6kW-tFR3MTexPnT!bFNDT`%Hg}RvFut__BD)kB511w+rWTJBs~~33j2L;G(I*V za9+C>7Hm0O?7fm3k^c+EayClo4^@h)q_bTv(`Dv&#rJeVXhLX9b8_9MjSV0N)vog^ zDCWDEnpT0kg|4|Rv_)uXjRGu!tnwT96 zDqLk;c~4J3I1SXIC}#Q0KN?iLU$FS5D(XKqIE#{z07OG~#daB4S8f&n96-xY^`CSM zktX?Ev+q#mep=-iI)4x0d+p(FF#YZFpiFjM)eljd3#OaJ?Jm}R?B~{^3p!T4w=cva)qzqM}w?Chg=!bjY2+tr%H6CJ|Zv6jKfU$x+_k_yfy)cM)lK!@J{($P^cmM=9z z7grrac4zD_Wg;iiEYvQ~LMc79mOW*fS$XBEKAf76*r0!h;@zKV6z13AS?!>UHeCtp zi*rX+^>3vJcR6Ue8rh*vS8!PyWX!oBxL= zqf5(c_aJ|JeK`YYanIVihruSzw8ufL{)-Yxn=um`1 z=nJ13#t&;e|9^S1*qHR_QWgmZZ#ekvf~A?ucScwQ4MjqTRC!%|J~wlr;!Y23zi{NY zzueeOQ42f9$BLP6G}t5$dDxd6%xRw6$z*PuAN3UfYdO$=R9EEC zN7D)F2#DJF{l)I8vt5vd`+nlg+rff_wk@$J&|Y^J2=Ld-&04$^MfH9WL`|>V?^vR+ zpKR4OY%y0>iGi>s6-gQSly^m{?Co{fQ#c_fzg5dpK0K=wAyQQzJ%VQsZN?gY2UwxB z=(fV#zOv7+ZO8&R2iUru7}oXV+qLCPK2IemWHE8s2@J*ZeS38<-?+YKeESZ)q_R35 zodzu6Fo3vC9UdNyvcs%hi$zA-jSiR%RIkO@No5`BQ>NlQfw^m>5T~|38AkNAbl`AG2jW8Hq zr>TllDgXa{)|>xlku<7XeGa6sbaW&#pIG;y!`X3!GArMuo56jh2SG73h44zgjVc>^ z&0%4`9Bp)sz6ulgC0IvFWYI$KqwanN^M5!06<6@2__p>Y`7+WEs8b|pUBw>M@+9-Z z$rnu4M{+{OOL{O2C4@2zw7*NtCZ;|mkb)Rc^5nyRCfb<54}A%{^9#^Fv70eA^)!Jeb8ui6HiAQ-3} z$jAG3i-P=3W7dk*POY^k&3I0%78_6Bhizr#av2vV(eD_=wZFP_NwV4M2^*yL>_X`Y zU)I0VNU686z4nW~Y1X=o9tQ|Bx8mnwgv!oAiS{=@QSdytK?$SG&9h!oMv&RRJrc3y z0UzZDmo`!-?qi|&dMd!^=Sj)zhO?8PUOOFwNJbGi?zs=7qW7XGUJ=V^wfA6Rra#0` z3aZPa-PP4mN+KE|=_#Ih)PYx?nAz|1HE16@r3}vex>K;tguI6+-M7$l!i&CEx_@}Y z6*hWqHsV*1nAyzF^aXUWsXiQW;msybx1R8CIZn8u)BUQ-~!=iw@UbcZU zrXV+Mel?i}QGnpN5c4d_6ZhHVC@5l{)G`7aXdfv}IaMgNVNM^*cGwOCFO{_Z!%G8{ z7fkSx|G8e?_|2Y*VKXrnl(o7@(Q+*-IGdC=H+|&p)c;+XvmD-+oU8~KWa{`z#$Qq5 z^mnQ-e+rTD76k#!0lN?9RLVGkrgOTSP*oKj|M_BE8qt^Yf`P6eTkCRuHM6&%+4vNC z7Uxi*pwmfa3`*}6eE|z>M=Mzfj!W$!RvaQ?;7T0jcO?zHwGs8IBa7M6&GuCOeV@Q@ zUI!f{bJCh6ZbdDb4CYkv8*jsSb$f)WQDc?-!qyTeLt#Vn9dByHh-F4X>!w27`2Ic% z3+EgVs%=a&FdStxeV65Dao~%W1lTo)`n-yw>Pn3<%Z+4km+uH|(Y2ummxNNO@I%!# z7CGQ>6+z)p+A@|%w9iJey9%crQiZcOCxW&9zzM#wSP}pEjLzIDi}GWhX({Kx&u=p? z`y(ZX+-bgh@gY{VR+P`dU?fb55mtzwG-M<@=>JjNM~}45`?78JUL_u*1DIOuCPy%> zYSGabrXB^{hXTNCdIR}epcU@%<)N)oq%9=MO9#wXW?j9h&zm$+X%H4Cf}i`cmQC`p z6dc&F-H>p~QlKD*ljL+q>&USeRH_sIR#(11V*A$V0UJ*W!95;7K5yWF^?{uD$Cm7P zRl}|P0+I1Zr5ARIP~iUZcuAgJNwDUiIp_Rdi7o48$@!UpW=5<+sSTS7+Ij!yrR>^h z=)J2?#y1{a&dPHLwpUR!51r-qo=)C9enV*DYaz4I(^VPEzODXMh4xN}2cYq&t;WJ| ztRO_9DiU2Lv9FP+vIr~gH{`{24$?*W)npf^GkI^MOFL%3tBqQTz0PJw=-FT(d=vZv9TlisT=PY7@Z`1*+)j>9Ky`8t=r}!(L)R%F4$dR~Kk( zJ}!y4no~XdAtz1pE=}Q4rrj+!1r0KyMu$&bBS}a^vOaci%mq@Sw~-F4{(0tCpe#@YA{FlYSX^E_HBC3srf%V zjz>I;e^^r&l3I=Soh6S)lc20Uu2nAuu8`7cj__9JYlmtRCu7lLABnOPfp*2 zm@3e*(Oay@>1K~sZAwip=badq)gf|H)|6gBZQVW5Eqae>7Es531Cu<1Cw#<>-!>@_W^GqyYt)nAKPPE(#3oZgzwY=Z5VT}fIpY~S%V?O(b& zt*YyC1*iLY_PTCGmYklw!x466R{5V6zQGH*JlCYowPx?3P2xE``l08oi?7a$l>%4Rc#TSp}@UK3G@B)$N1bi!+u#OJ6y$8}ajFCGuUmAAYix zwxMFSc)z0fpIT-AAhdIpDYW+M(oC$guh-msW|p{7p>36kJxOL-W^8??lw!3ES3bkS z^^%itsDQ>E!s&c%3Y{IRqD@v_8GnnLvRu8KgyL(LLkYhjdWIZGvsin;=nMMCCtbA@ zivWHbR7aS@%|E=@SyF^LL}2>#VgV{Re9$4rjup-Ll zDD`%=Xs99UWL2Yc#bm``&3r>&S4)}x8kR(`z*ir`iyY#WHtze%qU@SP-Ja~$^d1}V zGAexiDn@e(gfh_Y-d_9G(`;5Y#mq;&p-WQ*#-lB5<&!`1v2)&ueU4;U_j05a>y@ea=Gi8HGhAN% zVOheTZ>eeRw$P-#E@^K@e%-op`%h_~3)KGrhbc%_9zP}~>g6m@W+_(m=?5rlyi3;Z zlWfN1o#ie_H4`N`^0~&c)N_{Df|gpimu|CIzHI2BDxE!oKFv@N^3mniI`W386u;k5 zoHw|PI~&?^1i-vm4^`d{v97#|pEt)9P;+qJSeX1-55L{&X407Xc3tv=IU5SgDTT%UuGiEjp3jdYlB^l$=iJoF!I__TXf!tqZvJP6ztc)>XQ; z(#C^UpY>jfypn+vk<#MYPZ64b?wK9U?q>dsg*B)^w;2dZcm{-Kr~MKmDx;#}~-0 z*G;r;6C3S3^t-o&I_|@x_|4Mjga4yc(e}mXwhZKankr-YsT#>yWchCD#jt*?I?P!! zv)Jw*-a}u>3eHJ*x_N;SavLcjj2`W;s~XLH`NjXYXA)%+G9sPH<)m5+3RasO;|Zx0 zZK-SCC8%5d{>msunlE4B9yMrEo8qa92$2cZt9$xFPXtpU(m=eL8qIITQj!f46C)EN zBar~)fCp&tTU&)hE0MN_s-2guClV|f(Gp!(@>*vtC3Me*^7@(HTZ8BZ7G<;Px=lP% z#^!edaVG@^NOPwWV}*RpKMGV?;kB_c78>87)?59Nol0Css;x)oX!*2>Nnk~1nv#lv zrpqxJaN=0R;(c0ayWLiD!-EESCkOZ$|B|zw?y4NmBHP#(Z!m1a&TQP> z&bYPgPVj<=Ych}}m>v=_U6G!o3buR}S}Qj(smp%K!AF6u59L>xpnX%uhT?mz&}F{P9cj>i!f{S{x*xm!5&l_vi6jzeW+Ibow8=YrabTiR@mQV3#E~e;uwH6WLs` zrjYZfqkH3Xo8+i1(s?C>5=q78Kp7eFo1;!a6-svzK;4KTJ4Z?T&LMCMlZQ^%b!vW5 z&A7kV2D(1XB<$BnbR!+R(P8DiWbq1WEu5qxz+iCtQ?XwGTDZ7@DH{8|ED`R3TQP4( zVY&ERLgJhGkx1T`)LXPI#ne6rgj(|`H(F7kU$?WzSwA+TW=_4JGe7$_kBV_f*$zsI z%k=2{vPv*vEq4^Y6kz8L#*6<(&+)P+M|32;U^mB7FzU6{sRe9OMVo3hn(01%Ces$f z?o(DYYW8QgPZZ|SgsrN9M1dx>c5F?oc3;0}BX!Hv4Mr{4I5E}rb&8%+kWKkiPs@6G z*Pw2a?rtM}daqe*k?48`m&yzpo!CWBL_pbG7}qIO-2bJmJo z3L5IMB;Ozgw&Eq_G39xox{q>k?Ej69vJrEvy3HR%t)NF#`vD$Q)*s`=*D;gymV9i$hyFM(m9xQ&DOqz1bkG1x_yOe<@N^&ZE+guxC6}cSdK<5 zSw~2`m!gA|j=Q;kTX@+;N!FOZ7oSQ&V zQ9HRlbbg&O={4z8-_?Uk-eHsEQ7~x-+D@f=;LGq8cF^y}o2mcF%dgPUDQ;VGY7YKy z*r}7RYi7n#-=a8(-n{f9vO9HVNd~>B9-mN$Cb@jiZJk5|g|~|~(to%)ax3%fNnxg| z_u9+F9p#mvMK=d$_b}r+YD3;>8!%D!D!njNr}d)^I7Q7Rl9ls9X|}@;Lbm z4aEu)rZ?{**!_Iv^z~mUN)XqjN{c-27(YB5J%jJUT%o-o{-yO-3OTfrtWg=hBHeD2 z8vT(mmSu>HT0>zJmP*4VL}QWGcADO?`%Tvrq1SL0wFS<AEpjfQ+3E42lnM3Q8*DK zm25MN2YasIV2entH0`^Vb!3ZTE~+bW_Wc$_*m%gKjrEt^x8W7dXFoD{83m=dbvlIL zgL9K#qZD;z73MU#`)5q?pK$@8rE8FRLa=-+d;=&jsR0p!YiI5n%cxN?uqyfZ|_ zR0ShT$G3JyCUe z2eu4wU3QpM`;lw2J~fuf(=2Mcu;Y73_`N5pZ_O%;F>)AW!7BC&zPt*~#WaRaIu4}` z*hCU=A~J1~uk8&02DUs0PnglU@PK5!xMqt}^J(+&8h42=7b;ZJCT9(0bXC4%;8Ay6 zTi_|sa~RH(7GCFA<;xM-;Fy+X-_o-4mlmGd^dtUW6*6I>jBy>@XhNsB`tboCxqru^ zhkvhasKKV_2?8fPk3|c*77sO_ERs*C`d{475{%uD`+`Hl{LLv8dsM!2*~MuzH{P3} zXVQsPGJW?g+%xjSDzwg+Z9Z(7HC!0e5Xtf3P46Z#K4J_kff}94yv7ykATge6C6prb zP>4uL015PVxPjj<$*F&TdhBe?Wi(XuVzv8_7dNemI7L6v_@1XjQ51A0PM{OcT>S( z1o{tK2^w|FcQeJ?qV?3rbip>Z22udRaM0LiHqZW0AD45XaJ12b$rMncA*N=dS20S>VJ#_ zJ6I-{^*PMYbKFvOx%H&QuhxfA4m=$!hQ6w#>$ugHJZkDkMWbW2w4BOGvc6Z{mtVlI z2Knqpe*(&O%ca=7^sWSo=F!8bDmn|Oy|RwjE2_P(&xGJ^E>6A6aMif>>Md2_@yLo1 z&v}YODTz7_W11~{H`p4*(ANoKWo|oj=*~i<#y>oEBYiwmlV92qMKQBllE>WS5jM1S z+pXQ>PnH5$^P=M|;M2YPExE{Tph&lYmc4trXMXv(I@ISMo)B*Fi&75(*C89W*xa|X z^ox58u5IBpH(v*?KmEfy4=v8GEv3_Q1CUp+*OPMVCe5*whW8ZL26Gy}2VpBO1|yrb zbnD=>$v3|A7Tjt2+fYUOIr3k$Lqf^=OV~xb9V|_rK?W;q2_%hFH7g~5se4a&i71+p zw70_bVD8MjW@u~wkg#+^;S2iKfm1`EpAXbYPef=+sKr}Jd4+aHM=;U`K7vUT759v}HX^RKj{(FweE4 zzSdvezoKb)TSxN^ZzL#+VA(fbTqyM+NHoCe*9hzv0Q7AedKyy9^MEiyTsAaah%aX% zp$dPs@NRYSVZe$9ld4r(qQ>1hC(+^RmZOh*nhs!PTk8fJV}6Y|E)l3UYQoMExClEd zW04gt+@?CeHxPuknir&&Xd|eYqVL307GW+yFhna9ZlQDQA+}%yKMwn_2Ljs@^*|*5dLM z{1DDi+{YE|xRANU0OFpQhIoDE>3DLf2?@C9mbTcKrYl$$zg`Pkx{SLRx?LgW?a8}C zVSC$K_^wHE?CmR>wy}tv6nVS#`GaG@(N~v+#Dr%L^N`d9%&W`EoTRso<=0u1rTQYf zer2FpUTNZyAoWGC(Cyr0w4uoyaDPJkAKv(CnV)625@3ieGQGhyMR?>>)iFyCu3llr zN=#*``M#p%&DgLIq?*0{KnzoRyxvsGsr~|;Z$}S$Tj=sWV%P4Ygd?_r5;DQJoX2a> z7a{2|&s+X#a?+HrSR@GwkVLXh^A=Eb)JA$*@n|HkPq;)uYTZ*rw6dgsSY7*~<@^3F znD6S2$mlme^`4T%h=1w8dQSc{O}}!8BE4Ty&i!(9NIhK7b6oQapI){iV3}X0%DCx? z;?c~`%U$`ZX|LIDWdIombBYJ^W*1zDig!`Kavd5eTm+Gfdl(3uOv^7~13U5TVlP_z z9=l7f#Nv~09O206-{&Zws}TxKs8?~NhXLcLoiTD^!2Jv3Nv|n zAyP_*p5}sdicquBGxkViuP>*exMrCd1ZT`OSG-maId#cavTs8zAvf`~?(`dl7@FczeEgj1h(YBb2mCNw=vekJnaNFL4uVL>w zN*R(@i!paO#Nl=P5^3+Mh{K#y4Nd1^aQBG!RtGMF#sa#naHpcOi4fx@J4ksEFzq-3&E~%4!+W94>wal+Jfay)UK-K!2qW!<2 zkALSSv~hipcGq?z2<;x1xP1gP0FcmM(N4^IsigDvt*B}XhYzt#rNB^Fp`-q5TBZ!3 zFscg~iPX?J6YQ}uJlE0oS5+=u_zK;#oSDq>nvAFJcXcqa$gNabAI>h9(P)@gf7S8B zaUAbg?{nR{a42;?xzw&>!vmYP;z%KMc4Ta^dV3P{YGdu&iHiZm{-DrWK6*eyYYQyc zlf5IK_P(eWv)C~WH2#)Lp}<2_vj!ABR_?=~ge5hz_h`-JSi)UPuiDu%1kPS)W3cvL zo|ofl&%pjOZcahg*DZHVf;rS0d5!*LXJrGA!R!*LKjN0JE` zAKbor|F%ccZ6JIWru&ZZH)BP^az5$IVP`nf9aHqzK>D=C84-TF$u!uVMqT2{G*_pr zAEBfVI9%fdPxXmm4;6)Sgz9mKmd=#B=kT%v+u~aKE@_wk$A5NXW7ANQY^{L6N;`550Sm0GpDJh#3N@fU#(m?8WY&8iBjgCnPwo#p%6%| zW5!&6mmj%?M**9P)?V$95UfIp#VLhnv@)jVmz|d&@_p??+Z$i!o57_c|B=rGzdyc8 zo=AA=cJy2PUbGyQArXHYHtQ!_1C-8vv~zHjj%F6-nvJGK$-Kc z!O*H5U|g%HoA;^l(_3k?&8cL88Xe!Gpzh!62_xrEYA%nzEBPp2Ka3Cw(_JYu`Y=9O z<*2zj`QVr9`+kAYeP%4-Aai-Q_4B}{kzGE^rNOu;(g zHmJPIu|E+EG)$HDPjYVG z8o$dPvGgKfio={nE>p zSg|xZ-X+>|Hm5qTrJj+;xY4`GS>4y!$6!M_J1Tn4__Gc|gv-)zwW+KSL^6N~HgyzH_F|0*ex!!>5LWS7Uzl$sF^qFclo zAS5fd=ZKvO|G1x)mk@kmjh&7BW=82S1D#*_4Uukz1ar>i;PUA%IC+A@m+V%S+pSlZ zUrfcKJy`Oojb9!-fxV`Y>Ma32d05zea?kw!Um)r1cWnN>%6C9Iq*Du=eS5bSy#rZ? z`=nht`_?Q`&-!~{M(VDhS6)7vK~4Hd%e^rqTa{43p%l` zH0-~yVSX<917!LD$)bI5MwuknmasY&6Q3j=(!N5pT8hpEz=i!{&91V$ZqR{l1_e)A z+y4*R-mswEiqiF@|h5(i4>^2|vth zet%Ww%Tw14_uLv?DZUPDY|}1$t+eG^T;>k1Z=98wLxz}{20%e1YdF|9%YnS;(Pa_R_tQh7L zjo{r1tGGzju+%dQ5k6n@RQHH-RQf;m=OV}~hkKmP&4Vh8H7ue_emg{t=izWU&5`Jw z5xFQNR~5W59%k1zex6>(Z#WTbd@8xyX?`A4ba=0HAJly;+KTJ{nWJhWYUa{BiO?qr_9M*J!er>iYOF7E-6UvT)p< z&boXO=m(=d=w!MVOaDGuJsckkj{HM?;126bTA4~P zB`5S3tUeg|j2jhrG#=PhRASqbsoX=?so`0X-{lC@$`uOmbQXG>OXEKNXeQ~?kPfM+ zJO??Aj^Au&r(?0w(6QJkvU3P;cHkZtFAHg(TxlnLJ*jcwLam=f1xtAs_WXfXPlI*i zBCn1Z;~l27Eu;0$2`@4(W*z&9#5exqC#E`D=Ezq05v{eioE+!rS)4C=RcOOVL+ltRIr3iLDBIBHN!?_8j_$_j*syEU z|5sr7f^zlG^YnW72UhlY`rX?H5MjmMo+-iMpcRX~cKBmJ+YZb_-t8Zb zYvYU)p*2&~VmC4KXV7ep-Wjg3dO?}5x~S6iHl#P$ooN-p%f)V5Rgc)Q^Q)R?88mTS z1P9v|)Tx76SL$CE@ZNLxu;6rKkR_5K1$a?=Hm{`}4O=rBKDC)hyu>N6vg@1&kH@~+ zG?0CAv`h+PZFY+WS%_?CscXiS#C$AZ>JREK9k4F=AAU5kytsB zT&dY}nr~U2XiK{UL3g(09HT=7=n5d{*@~lke>T;tVeD^K;(jV@Met(`|L(m&p(mc! z`fo~u$L^g%8L-W-g069gfQcT;NVwC@0byy{&Ga-^lJ8F!7Nk|((Vt>|N`wodyJgL< zF8|W?$r?9wz)+)Z1XXc3s+cdNDf~jsyrAn%m~0sbKNHCt;?jnZXZg`dqqb*XK2PMk zTkyP&9`742nZ4e)%oXze$@&FP8zF5oa+1{PH_QUZ=e+tF@k{3UCU#S*A)|d=s#{D{Ue=r^=D|b0#uZX|X)h zj-hYf4EJ*~evbZKA`8WezL?>p%l^Ih`PjZ8mzu6$Mr+i*`x8HLjyUfait0WG(u5Lvj#mz{2@P`3Es>^++Vr_4&+(u>J#^ zSM#=Q2;g3-qZ=GyGe=k7i~#bJxxqT~^lblWoz0 z4UT?E-)m#i?-Kp!N{>GK+Wh%iwKZl!$jQJWROjMi1HNo;?n#~ddG3Yj?Tl5bBqVI( zR{Nak@Zg1$o++xo=k(jey>m(qVV#IqaOLLp1|JMsA)@4y?_!u0xyS3*J2lrQ$@e)K z?6_KTJaS}+n8bdqekDN)d?@9o+_8HQ%YnzBD;P+P8wha ztE&P}mf5)R74iw%KF-zr>MeoxjT=g_Ah-NMmM4MmaWBB82-^~H-a7rF?w@n!2Ql5pilF-tY{}KoBmuTBgFd<(l!3E$f0J!yaimnr)TdOu zBy+!LE&V{7-S~vxbCrBLP%)!jNs8)ab2a!kwO>YiX|m=Qs=o?c-xh5GzZefcEG;0{ zy%H6uekygm02HrWUmExDsK5?z$(w-k*#J;zYo^lpr88m>{?d5Nfwn`@u#Ot0cF<4b zR@W_I3>85)C@p8EU4=}$HE*l&*TKunU>J}6B^^qwO_pi}(1HeS6XOy4Ll@2({&q0u z?%}0Fg2o1lT;n-0VSH=a;kW8-li}x_(uqwOq0kk9};Y$YhwZ9XKU|c z7Y$>GKt-&lSv?tZqUt?~)gU!u@e6G5J*8@um_WhR>xngDLfn_XZh0jd;xAtUu^h_C zo6XXWX12tgX?jrC%x)st(?cFG|$b> zM-Jx9PTc%sE{$ZSDYCzFyo_2O3Uw_I&Fc)51M{%yc)>xzzrFe0zwc@MosB_L6gC7* zWSBQ5J+IRWcffxb^ zvMj0YwqPtu6BEOZZp+fUhO9$VO0q5tgFy9$gAsl8`JXQ)IVqI49TGv2I!~Su>9`#w zZ_sJ7z2_OO(e9jg|GHJs^w(ZsdNbdkUX`T;pv!orKND$l%w1^6H+xtMH!@Q4$;=W< zDaF9IFpX39TPV8k&(h|7w-Qlt;Ie*5}z!Emxk!53}mL*Vui7VnZc2XO_p>|d+hZ6egFrJ=e4>Hc& z(2!5^V*4vTzYQgth3QyEr{w%qGadmbZz^wCcK$Ane|C!`raGS*|FmNExozVwy2Rkf zyjyky(w*&_{gAZ?1rU%xXiXaCjAIhusq3YrKQuzyln@SIDT3mGPZ^+MF zjJX~?0NVAF3*NB{?gPhi8OJr(?^bxcmJwmil_=o6i5jK?lq}ikp6P+NWKq+QV>!Iw z;tOzFFK<8bX~ty|)83i2#(I^kX3j~kW@JRpg#XNbQ7Zk#ZqWQK-YKJTvL@mzhj6&` zvkckqcw9JA5E*GcD15)Hu_&gon=Sa=Y>N%BH1w{n9hTKoZb!f}yFNINbf;^em&|X+DDS$O0^uY_Uj+c)5=3pw`6p_!RlI%!HL+|M+Ezx zJKDoPZ0zFu{VsOF-rWEq@d`28A2<2-CG!e_E=H zJ8JwBf{`;zvRTwLJMerS5E?I-=$>WCzwF*V23-FQCm+>;275N-Eb3s=juw0u3rU^d zyXVJi-1UwZzkFK*)3~-G{)aOr=O*)|-0)7==)>FRa<&hSUSbrVyixHeyY$zx&(sI( zt8=H9_nglq!InRIqzS;?Mvg!q=4MA;Z@FUVf~WOAJo^2O>K_idwe?t$<~DAqo>Qg6 zWT=IK{Guh4mDL)1H%$+fs)k*h-%O_iTAKFnU2#R1G)mzZ#Qpo`V#(yItz5i4K1vxA znlqzk0iB(u)5K~uvbGG1OD`^72z;9Qtj;(K<12>ApOdi)&YCm?X4fr-AW~3Tc4gGu z>G07l;oHjU`Z9b?X~|oWKLKx4%qLJOaGWsh?zXt@PDLev{HL*^A?xI!Atsfdvot>v z72Z7ap*849QU*nhZpueLd_uv%%P?R@`gG1Kg@iHR&aZv`6_3QFNB)qg`79cKzD5sC z7QbNHHUwl#=BA!+NW7k@vNsU6S&|{X6L=!~_j~k^U8Cws#QA>ws^-G!S9TKiSMhev z?JC7-x8MzP8K;3UQ}rtY9hZArK;25YhVMpz`_kn*w4Q&Co=(fJ)v(V-y}sabf)TWM zol~qxH0mS_2^Vcn^`WNV_YMB0kZE zX3adU1AEIIG66NymEe>blI~+x^}l3XEpIwXNW6uR}Y(;B$DY^AzA!2!Pm5? z)ywIX^Nc1~*67yc0SP6Yz^Y|w-eK;8zKxARl>s3&dSQmx2jMg-+Ar!qlaPN+xgioA za$h<_=}yYF+4^)Xg#qN&qEsdm^`3C#CK+$y~MPTYWN>vy%p)^KI=_9 z{Cb{UsJ4#CNEf<4UV&P0yHZkwY{}wo0jE?#CW-_gtW>Q)QSl>7>p!*QI}$elt^=txeZGCTE6xnB{M@8_U)pB zsnEao_bFicOZ}_4iZZ2o>f^I1CI$0HQJ*PkV!o9K%-As;s^%MI1(^@6d#X-F#RhF4 z2_7dmdYaEV@dFIi+Z62%ZOVGONgd>5N{+J<2b~s9UZ%J)e0CEO{a%QenOYL>WJ$PBYNi1(NsF4#>+^SaekYy z^daWQz%~g}af~~Vkw1*(s{Tnk^GpJ)DeJhV9J`yxCVZ*F_TlCW^{>VY9eNn)&i*qiAK2A?6YRtIuS%w0bU|oEOB!79D03@ z$s{_Q^4K^}AQ0As^e76;p~v6h;9J-}iQ1d)$GmC4NYxm`9)%d=j~l%;A$P<}N=WF1 zUh5g^PJRdonWkd%ppET&nkl;n6-l9X!4n$1vKu-}F~1(Ek1fL;Trv)ZEqm-QgZ92< zR&ck0dVAGxdMk?R>!)jO%Gh?wL)E1W3tgv0%r$)WNeGEq&HCx|!m-X#mDWYYsV+|I zOK0XLM(;&Fw~mL)?)HPfb+HwD#om7GW+$?MckjK7xZ1MuReGm^j4MXFiiUH z)8z?wf9%^`XwsoF&0n>e8SzEcq%c_$B4?U84sUXj-x(Kr1v^6u0`Vh9Ok*g+M)2vhs^G*-+GCvFe|Gt}oILY?{~yW187V z6&!8Ye{`xGya|mSeq+NhHhXekL(eyRE(E>nSHcEH(+$;YVfSmiNo|HRtX(;e%cjiB zW>*@7^q!_SB9jLljt59G6*p5Mf2JbIg~EsXV>eX7dS zL^#5pvjT{{YO!?;B3Xc~h?D^69^J&k^1RC_U=iwl1D9Isv zIT5UHa%X?{9@_Cn>}E#x2g@D~OXIWR*Pz&?1HLSrI0?4J3OYzRbKcO|sv|X;x&!5I zY=q9a)X`F)oW#pZ#)IvxFTP3(t`^8EIgn7B<5~VwMHrUe?6=AGls;?4=T-In9sx;y z<{-XneIDz$t7wuoKv)|I08v#{koW5K)ZO2!qG4->c7V*t`$>AWP;cSGirh&*3H5Go z2WqDJxZ%gi4*`8ukqn9xOT~mqbG`s?Ko#@h&d2lp`Kia^Khn~pnK!nt-nk{3e%dy!Vb@{($x+p5 zwP!AU`nydQX4(Hr_!6;QYgWcaHKCVPBRQpIO)ZYlES~ubrb*vLKnsrB7nF40^a>zK znLqqWC2jcZyL5(3ICgSqf?;~6{)F_gQ7Qo)$ZiZyp5T2Dcnv${jIDuPZi#OCZ z51T{xfNkQp$J6NnZa?PqQ(m^YNO&2sr9I?N`%zHCzq|ido)xLzy}X}aZq^ilLMp8^ zFbhW*+Nu-z9y+rp|A2dsT@PAeP&dX>MXvQa)3jX%g%BF?9x zV_+hZ*e0L~FZzc=0b$N+aoY1O$m85lU?-VtJ`r=1SZw(rY!8*7s)8h4jd@@#t;Xs) zP=6yMjSJOmSp~^V4s+i|1T)dB6?cmp`D!4CDAk_BEe+ zBZkLVO+-Y^VNKM;mS2^YWOwV3*hoRJX}&wabJ=fK)3m~s056FD#=h+6RSv=GVWD{= zhGDEoUZM^i{r&4CQ@U!Dn^5mxZpp@oLC1zH4yI+b?e9E$X2Z{8H-5Y&pck*+-bQx` zzfc*Rc(W`p8?U{Rk?!vd??l$H&+ad1y>l^1S^`wHWa)I1L$~wIj6YOiIer$_F`e~$ zrp~G>d~-RAP@~0RB`+I-5mssHj`2i7xJv?8gwQMohohWrn5p zN(r@;tB4`cwz;y_G1^{JTdznqWxqaVKY1eo<0qo_2Mt`He>m^zR{Jnt-Cf6o5vqIE z(faKNYvO&V!COsbU(L}r9}gZX2|?LvN(a+;)keX?=ae%IS2|wa5s}U&8jGM^j29+$ zw7i1%>~CxGiX?aB8IYrChm?oGMcXHX>kgtQl1&3TDe8F5mYMD6xhKYObH8SMqcT~@ zg9-CLFdS6$*p=uzJ?g1;2OQMI-~fA+glMg` zXgvfpy`0~hP|?Z}<(DNHTwkWdx>Gl^=WayJ{YcGdZ^-tIzfGJv)0wJ%5EhD;`wSY{ zJM161lqON5T~na0S->o**)Qe%h?RWt>1Kw;1#&Vy(jHJ#N8hr55tf-VU&#r zT&m7B%qrInga2^w*i*VxKZS?IrV;T!&RLRHV(T7nZ`)W2U8~$H9Rb3M<}(1&m3gi+ zzasyeJ-%~CAMz)re6pn^wh8&l)T%V2(qwz5jK8sqLgU+whyP3r8LR4@BKvD$@z#88 zJIk{?@)`QR)2zXucBwRRk=DIw#dK_&yKJG<(xS{~{Tkre9$a6|XduUY4+hL}X@hFd znG)s?jYgGKhDz}%lr``u#czx4*AEh2_B$mdnGmLPULIsT`bpBhEH?E@Hn2%bDsa!< zHj)-r+wHx#Kv7rd3$&Uon62P8Hs`Z+H0VyOzew70J&(#^Xy;PP#U)Rm_?`WE6B`H1 zvR(T=A>ie7ul%GS=i^;nreRqMGwK<;NHT^!zm!FBc|gmRPJDW0t>jR1>rEL~J3=#8 zoM)}j`si*99Aj*=A*RULG@Y{fG7$FllS*tKS}0KB>G2@6)Fm){+Dv#;wLm5-Mlq zZRF)E0;j9_BpC(lhM{E%F$P@oT?UHG7D-ZK<#at_ftIaru%?zEa3DXvXk%NALpseN z9Xg0a2A|k+{)5q+gU+^WrhV_JHTj(=|D*uDwR1H*?JXWryqo!+@v9QKG%9ZWb%8|l z0bPjuGSGahEocAe0#2lpUU|e@p%xlPpZI@mgUg1myQSMMvEELvJ145-PZ^$+A|2-< zu_Jia-%=tz^AO8B4vvQCsI{f2llUPKJp*i7 zGhD3QQ6?E`tiRj!dh%FsJpwO*AANrKA2LijQa09RGsHJ_zA)1V@GMppPlp|nGFJLV z{KHXRiNrVw2YKYzIZ&Sy;dE_C4!+IkI7-XNnxlmDV6Ua3&!e_P-2H*?WV((XIQj z2rhz+$uPG2jFIVbo_&(O@IDscRoW4F^W#RoV>&rW4to=cGQUGMp9)`YCz)|`%=494 zzYwob0dohuH-J1u35*Slhe-Fp#{H%bQ2}@^p`xuE5I9j-5+?Bi?dzMS?fKKtP^+DgKMkj zVet(OTT>i9kL9?9b>BG3z2;#&tVgAj2sHe|sr|z|XD1?@yQiZD%Qm;HwI+tmnv*Y} z*7o^aE5{MTeF-KcmYbW5+~v}VL4I9`Fxt^&%53_AOV|civ3S2 zjkwsr&7qY5ovsJ2l8LWfhkmA{`R(QX{+;1Kj2;p<^4JK*o|(a>#v=S%&DTsk5Qc!; z(vvJ;rx!ALonJ}^S0L|ZbU)n0d|8iU5YNymPgtGOWwBCJWvmh`Z zV@qO3x(Wj8m62L!9;x|;T6sNXtvBiAYb|iUelui;evO*{8Br?F!aMw@kBH+bk!8Te1V zAB)XMDq_w+%YO>o2V*DP9X!flcls-mb9Btr6{QwNrE97zO);$O?l$Dp98D6@+v_C- zdsbPV`+?y!8FZ0pOfge$I4BB80lZ+BWl;P;n>w7=E0F~Yw6FY)lIFeLc)d`pBeBEq zb8l6Xm_K<2#&~^a;d>|XQBT>}Oh0=?xa2FYtP9;$8bK(jbdrGVKrY94y0n0<(5;Xc zg3Y38VS;3SlsHR*7h0LGCA}p)LOm+hin^7XAI~W0R>1US(5uFN@ToErC@8h8`JHB? zCnh_UD4NAl4=>l0v>1Zg_pj5iVE$rBE9l2$;YBVGUSC6V|1%9up$gU|b*OK)j58Dy zC80bEa=$jaH~jk|b83^N&XLmGf94&K_;k6bT50yB@r1SEobd9DYLD?*WJa)P*=L0Z zY9hS33h$qXaZotU{#xsNs<9xy0vYl~hHHvApXGbso7RKdeKK4CTh@{q7Z#Nqp?^}| z`<|*YX*5k3=-1j_*)UHD&ZO$cG)CCHP4KUZ;N4& zT&~xK8=$wS3VY>#p^SQPKZndN_PE))Ux`G1yw2!*v;mT~M#=al1@eFsu za6$<@_9*q3(wk=gTH0Zj%@&(eKKkaI&=jFd~`y9CTpAnE89;_b>G; zT}CJ63YTLCpE~#>l9)C)H-CQ>|NM@nk2I+#7KZzjN=bx#dt4+if0<_b`j~Xy!hY_&?hN@6NgwT4RSJn3;tZ}(QlZn0>=#Y zIg$T5vQZ>l%n|xb>&^duE?3%NW=q}+yEhFRv6lVFS%)R_aU4hPYn($S6s)8qToc@;)Yt8|sgh|8tbXDL+=mIvW@O%~9{**T&i}S^+*($`qv# zbdUeZKb-JUP5lluw~-nD?uMNu$twWAPQ&wPon_!X`8eR)B5TSWJOm&EMiT~H9}Xj zP}I7n6!L0?A1AcEr$-fpuRSS%U%kp8u^+z9yAR-5skSA9a0uH{SYK=OxPKG>UTe-Q zli)CtX;YA=x0Ne<8HOMNl;^i(y?zHUvqsJQ)kpySntxP2$v>8#r{&Ws>Zz+8`YE!) zNrQQ0sp*`Jj@r&n9@g66BVXeF7GI#JauSFbcnniH5zUCcB0F%&-s8V$XkWj%7}CKS zJ389vp)d=Nqm)f;x5c#o1CbDc_K4YNz3$kNYWkZeObG^^=rCV=O_IbTZUco{db2OZ z;OBtsn77B@)g0D42}{rhEDgYd>)Q_wGFpS&+d4}b&<Nk7XeHdC?kwiih~rp4f{Jnik*16hmM1 zPU1!asd%os!-BLLIeS)a?sxzG!x4n@&8B;_LT~Xwz6V{Bx7o+7*U%$V!(4kAzLz_Q z!*4T9CN*{x6bz9t!ePGMtRfmS*D-#Wo|%2$M`;RyNGJE`sb}wFCuDL|{7=sUWj!u` zUs{!yZZW{Fctwmt@;ifM2eS(b%&IRcG|`t9MHPw~MIM*QWt7TE?FJd*E$Z4w8`TCr zN<{UbN4Fk;Io#N3j&kxA#p~1J3Z8q~Bi>h6fbK(eIrG=(t{LbGr0z)Hzk9WldYOMJ z@7MYA8Zv|Yqp|U$e4Idq?)(Nvo=jE7Q-2TUm^@fIz{dTdNS5L^egq+jAZH>xeTY_- zWuwj8=uI5XJJlAq5(AocljFvmBGO;+Aw`~zV`gPNt(-xF@qu(8^!ufYUw8y;csSNB zhTfRVz3(G|*^nNhc{4hN%|(u;-TkskwYun{nw)&D9f&g~Lo2$tS?dC;dUHjKUyrJ-5=6zxC4T zwHd`pd1>=D*sN?Y!cNPCzu77UE#{zRFiEKCDM~{MMhb9Pm>?xyE5=P6ls8srTQi}rT7}-5W#GPK^lsXc0sKIuVh$L>r5Tzse zQAp8rY%90=Qmsu*^p>|7gO4Yk`S6Q6i@>5;yod!MokJM&6MB9#GCB#L=Nr8m?+H>I zeg@k)D{fLfqPs>$11!D-kK5Yo2X2vxB~=*AcJc&wkF|pfyr#e%`6)Z0pZE;B5Chu& z#F9o1$D}MCFKR05T~2RXEa&T5g5=zYRm%X&5(^HKB4$mYr9DNZ;JoS`_=c~08_$u; z-<9k_bIB9U?wzH!?Z2@dR3bbdrgM}af~QT5+3%o%FfR$KGgVwgya(;KhH0OaXxl~U z@Z_UM|XUtCEk3P!2l;9fV zUN#f0tw2y}bYYCK3{N##9rt`_aC1uV>1$n|itxyX<6mFn&YsaeJ^~r#q$6Rx+DW~3 z@-4lsXN_}rAw}opgzksBX^CaaWPWgVrR$>jz{@sBnfQoFra2FY^Gb86HhoPZA6CtgTVB@W$Za zVP22}#{aq}Yaz|HX!1TIB&_wX)TYXy+_0R~mE2iaf2iEqE6cx>%lBGWUM_Vgee^nF zjf@Me+l?x2OgANC+fyK+pgFHNiZ|;Rj8Dbq{!!;ZKEv|-C0ckskT3C@xc@sE7WnWk z6pN6L55j(}ee3LZ$8&SaQW<3wiTNc^0QQx6me| zanzvSJqhV6yX| zTGF<~?mI!wAFh&UcBN>W@>;8RnkZae;!MugZC#$1C6Zt)xUZ!?I(gw|I21!m){~8$ z;F2MBJ$`>f0CGB+mLyt>|Nk}9v@P=AeF}1+On?imyQ)iS3+Js6xpG0sU9${88?3qt z-}KlUu}$Pjx3Jc`u_M@V*J*cmV0}+BZCQ}NiodJjpG{pT*nDqc<%qGf4QUXY#&IC) z+g0;c<%{ZQgvgVs8a&So=3i5J1UV!m>T(Q>;|aKpVuvcKt8a`Qey+(lP3I+}DJ^p%>f1`Xw4a8n!F6GydKMzq`eyR^)qgP4KjUecV-k1yRGaOAm9d-K?JY`7B zagZ6jrmmfJlxc5<)a=?#`hVY2sdYNE+&in}(8}PIgDQ+|=~m~dB{6(#=B2hkooAXQ zQsNy<%TuZXuBS7WT2{ z?rVz)Hjv6sBsJKacm3Vrt9gp#th~H@v%-2HF;bJ2Gm+QXeJgX zEAVv84Jwioxhru#A&+~NnwvDVVd`9-xOZyvtTUKSIt)ZQw6C6(4YUq2lpyam<==@zl9ZJm=B>WHO?SJhTDzw}+GkUZ)_`Sb$#+R6j z#IQUJ<9aku{w1TnQ|QNbyh$xZz{2R%Gc;4aP<(wO_xJfFSTZdAjY~V2ZA}>P&=k|; zd@{BDUBfjq0I>o&h8Beo-gN-cT6qwEegC8BWa#RPRv?3Gf%!|TKhK+{qc7=R=L+wr z7V5HOOvPtr7{H>U?T)Ks0@f8~?ldqChw|d!)EIZUtvXyuez8;TCV#Wp^n~&Pvo^6r zaR}ykd$@E7XzHS`X8H?(F|?_K*B&bCcI_`TaFuC@u)qiA>I#*T#R|b}=nzw9`c-Bq zJu3}8dJrQvr`dNG)^zKVlXS1^A#!B^IWi0yTFE@FUUQlHF}59iFsd;iit%08-E1Xj<5Pb)>yZRXr9J+=X}OcsO#zs7|fah z&Rp&r>Zl#xwVH(H!N=R}39T;KK$0z$DXE@YnF<}T!|Z1165Ethj_)Q(=b{}O9ISIIp_t!gVbv(5EJNj$X zHo2cHGI#Ih{XsQzoZ;Fe_XFvr0D3dRl}RBA1GQA>U2PiNo6XiXxkY84!#G(LaZe|v z=#W=&8Pdknubz{nLscgHJqWd~yLK`V;_v1dsAu3OrAf zYYW^?o8J4I!>ai9mz>v4Z>w9fVCl!Jvg`l7id*eQ=%x*!JX`|;XIZd3Gd>!!(ETbO zv-cmG@&)l2LimI(`^i5nsS`Ufa|>jCDT{jIl7RdBYOwG)bv~J{5>3-Jidd@o<(Sxs z|KCNFIvIj#PWp`BzcP9%!_stvIjU!wF~%7#C^+1%F6@s`VN;H1PK{11;ta<9!?gM2 z6ETCQl?_1~^PSYT-4aYcBa?Eaf>NLL$fUBc?f`yCBxE*F?>p1~YVsb(q&~<$zVw*c zw_#$1U3vADF~9<~aplxgYwq+X^apdAaz4zbZlb`Y!|q-wOh!pdM0W}_xQli-TteM< zknQg+1cI*ko(bJKfpYZbU|VCRx`q!p?LV5q3wlRmD&4Bz=66otl1NyR*K;?2dMioJ z_9ael#P(e@o+n_LX@>gMN~?zTv7bk-i!vYk1`yf7I!_Bj*cKi6i%_YnwG^_szL4Rf z7ZLpKH<7@%AGp-_%tptcN61GwqJ&;wS29mMDu$a;R$KQ|vSC8sq*VL}^NEAvk(Wwu z?gzEjl{fE0Yi#>d#TO5J^3?hCGRw=HArspuupZ0Pm5i1RN^V#28Uu-@W-Ts)%9`Bd zI^O;0={h$d%<~WL@jv2Z^|RXx3-8QZU(r*h;xTv~M-?74Yv+sF)TgZ6>=TCQTgog5 zS5VXnFZd!YeI4?Aky@=%w-kz%H=p@^$~#)e*Rv1zElYOz`KI`O6|w+2A^Qrown8|0 z3L#%Dik?##vK#qY{oHap8Fx96S5AmU6(<^Zx^9dQnpSXoX6hR(nvPEHw@xgyJ;`)d zp35x6HlXW`%LS>+{JQ(h+A2PcE9g+Uh=%CIM$7lPy7RPE*toJK4-}!4KeK}5*XZfl zJ$%luBa&0Xxc7qfS57zP#_g9w0>QX&s2%%SYcfUJXrSCTptgO!%xI}*<_>$ zAj@6#Nut@JfPNx{wyc2o8{h@tyMG^Z>6na@VD~;p>B$OXzFwOyK+n+9Z(+*S*?acN zIke=zIe|w~Eh|i>t|*?`s+VnAfy1`M;lZ=LNQXDWYf#+JgLdW_9rP1 z^PTeg@LR8rso>_XuYTtR3uCNT4S9BHTr=lib2nUn+y%`9bmn=mJ|K)5(j40+X=br) zbSgKKe{`nC`f03RCFU{C%k1M(Dk1&bNU9_%3207z5r2Y16?YTdxfRH|?3-;G%!W>5 z|DDx6JTW+9=#|Md8L69HVgO?rd1uq(E!veMs{mq)bV3`K2hufbXw`)c6!--6OY3Dz~dmV7+1 zUiXf2^vh!%YG0zBA`|bQ4fwsJ{Ea*5Dg+|Qy;fe$LN{JlfF<$JUkyepAJa(L%oqpC zz)DTtQt)iFWso z)f|-q&tM9*1to4|zk5mjU#cEQ3`&DOxZi|xDkM?@8~u4ig=aRvJvRBR&3F>*%L(Vg z1@w@;;GK?YRw#*u-s+a|fsxUnLqXT+jju0LqsGWOEJ{vK&1HFVFa{k{y=P2wX7wkh za>wr^&1vpa_^Ik5SjWz4G9uu&S<-&Vtmn_64g6gR`GX1(@=^D72x?nhww^MWLcn`_ zwh{@}%vw-roj1D-MZ2*oaY1B%!Uo?Fqxu_?>`ee1HOxm>YDz5@@6Nc%pq^F7@#;`W zc_y%OguS!~cnk-gIdOa3JeWxY;R$5TPNwx+?^FlMV;m$1T&u}v| zP!Bq@-wtxn&CPn9Mv9TQgzJ5dn6l`>;ixJ*$=A?AzU)`v-fE zJQj^J_r?oZD_T~=wTfR8o;W(Sd(LOgf{TDa3HND@vf~^NGnYq;@x!pk1AAcnN?IT> z$;1qsC@LS6Jp&g(`1<|BfuKUJY3)Ipx4J!TZ0Uy{N&F2Pk77iNk=Zx+-7<7gLXs}& z%9=0tsz0*w@nc7V6FTx}9%g>5-tCV!Jo0wV2wxJPb)kz5dkOec)Ql9Ii@Z*UEorv~ z0L?j2JQlgUC7fumdb4J;d1&h~$kp3tSc_`xBq2WLsQumMVNq?6f>8<=iPa5*q2c%s z$X#3l>52!dN}#Nk`ht&QUIsqY$v0#^hvEX9P{d>a&RXBO^EcP74aAYo&^_oRhJ5 zD{;znoVXKc3{f^?c9M*m-A*H~DUh|6x4ZVj=wl@d{Q?#T1`0Nyq@JR%5u+!jCFCgJ znh@e~ErsB(^U!5X)_ULFFjt2~RWP!r@{#8bre_%wmRhyR{&o^Ld*hv5GnvJRj?mNg zD^=ywYiQFm^-WLrKisoy#Z%6&+{`kqgxrF^<9a+U;K228s3yz;n<6q15yB1r$vN{c zx81&JC{C3eZ3VsgjX#_Hc3438ST_GYL5$?4ggnn_VwA@NXl??BcP>zxVe|4d>lz0x zx(B&3N$D&L1Mxj9>0u?yp(>nUO*OGzpye|5=<0vwS&+UthmQrgV4#{Nd9r=;aM2C0;tl<* zUc)k>yjvH0C_fwVZE017+NSA{ZUS&=EbI>|>dHr&iOZXb#-PL_@TS&;C z$|BuXG;w7EN_PC`1InA`&*ArBt#=*Py?=N1LOj}TuVPy;|8P|H*)BtKP?%zk{fbLD zk3&peXb<9>`jR=C@^xc?=>BHD!a;I-^wJv_i&B^!>WyrgNlErQ$j#?~U!aF42wOxo zQ#=v#FN|sH4-(xsM5a;;ensuZz>sr6yz25J_SqnyX#M$Jk~%-%*(?a&cpK^{nz6YP zb2EFfE9Dn+)b&#la;7YCwoz40;_&hGKAgh%&U5h3Wq}*TH!8z*11CLsv6&1!Ifjso z!DMr%i?GkJ1)ZbZ9}wqCqZRrAWMNuPjF;lghIrINoOj?rHeflTP2+etBbfa@ zE4QKBWUtvT10yUZvAT8K_@07Or-)M9=*1CJ8Et7q%wx-i36{|@;|6&|CA8-BTjX+i zLMAyH;A<=c%P%u+Q}GDWzk<`+1A%@WdPhNZYFDss3CXbN8tS{iF(@A;C{oC5lJuzVvCGt8$v(`NN}d0ksdt1ucibPvmMc%_UFGnD?1H`*Hg1LdloP#JXby84 zp-j_y{1JSMMVnmx2#}iyTfJPHx$jxSIP#e+)hGS#0gg`Qg<%gjVU{JVSb!ty#q9yV z5Gv0VLI zd|te=sekSW>*+Jpzph=F?@9G=Vd=UbE%!G1K|x%aQC-zvS2&D8mqt6r7OI_pJO1>maCp> zL+U$^kpMOdaEE>6)!8|G!)zm>rck1`$*%&~^P0-{AW`43(nAulbrU8(`j_igkKCTK zgEierMeS6jRPj4tBB3Ded%*xk+BD^<0M1t5?=<`3uS^k1)a5@6CbenMz|c}4=)4A2 z3y`YVDi)c_=+P}OD=J9$28yH1%TMAr>K~V!_Hkx2jTZt%#19ccq>0CEg-&VI3@3W2 zf_a4--Lv(njFx9o0b05=mfv<+3F>Y`EJF_JrA^UAH}ypT^|dFn8bA!!_XYRYYnKfH zS?GZd@0(>dkNvEkj)uk>=7!f<$#_tt-IjdigW%LlrC=%v;$BT>zI|#HGvXaTFP$wF zavIt1Ow@I|3#kfYG0geS8rM)*AC`&fhdB4U*#3Wrd(W;W-=OUm1uJ5qDfAT9J>Rhsk;l2DXR0z_JXAfO;1T}lWfgh=loz4PC>pL_3*@T~nNFR!(7t@E0h zb7qd?M~IMa$@{c}4}c6K55 zp=kH=pECzLU5U(`q!`LK=nd;~M&ZNpRLjugztoAee`Hf{T9*8UZA^+d7Nq8dCbEhe zU8VHRiQ;h?S}g9JRsdokpo71D*;YIK!1H+;4R0V6v-|3I*j*GfUVhX$$Zg9?+@W2G1J`AInT zOF5}q2UOa(&kk4R`cmRh;G?kOra?VhAv5si0L=pGKKb)P>N?!sDwK27PV~EZ=D6C? z{=HqekQ4@d@@^3<9#a=WLUa* z?1m0!n8K4;7d}mSXJ$K=OKTi+M4EPJ`&EXa6?sd0`3nUL!W$yZj;orjBx0=y2jbnF zQPMHtTqGLL1v7qqmpI6hJ!+^gWxs`D`I2f@O-ND3)u+B_Gl#3ZtWcMP!neGBOW0pJ zb_D)}{0?wcu!7(0#rH36`y!kEVcXgfjy~svh8^n<=a$RbqZY2xjHy23;o47|tyM9VZrMRPHRskMlTegSRFU%+d^;b3&*3 zx(wf8J-(=6w_Z%5ua1>1O4lxTvhJJ zf4F^7p_(UYzXNG|#N6EQH?lupUH%aS{|ai#oFC-8bM=CNev8}D zKLz{Ib~=|!+-NN|{%tVyPI3cQ@`2^~jR`~;!G9!#k5PhW#IZ-`%?&Jy>OT^Phng2r zS4xM>+o#u-H|9himL}6InWGsDjj^=op;xNuCaY-?WLb26b#su4rX8*nhVRlWn$>cYMjjSIJ3x#)b#mna&^T zAlWrmcpTKf>VI6gAiv=B_oz;rLQE7jb1>S&X9!b4TSgT#wLDzXI|Mf^A-C#EtiiS&K6ada==SRET!+?+TFyWy7ltGE2=W`APL8M+Dz#= z-O60u)LL`&+eVSzd$%S0@3&0HMt@1^o3?Gpw1pSkLuUM<_)@X8Z-j2DjM^Y8KKD&6)&LmA@_^DLFXj{=uLFGt1#1fw0dZSGPGYYwRyk41q3G zHa3I9+$+7RVOwc8SK8M}Nl{IRW47z!|46U}ri;X1xc`srTKIkCOuuK^|oPzKUUyODJQJ@Nd_no-~K;;v+H+Q zsZul9@dW4$Eq-{YgwT#3M&qs2*BZ>>7ogBk#_1hYKvV)gwAp63;O}AXzRiwA!82>^ zIZa!Gu5<$jcKao+g2ZIN<0`9mN}Wd{j2pM&7{L`P-qih-FH!Hu!<1Oc14 zL1fc@B%vODb6$na$~9<$YD*EMu2M+nU5-d)C{_2Sc4=44pcxx&e`hD!<$a!<}l+NAD<^EZj{(i`+s<;>lYxG+jV}c)5b=3 zJz_O%7_ZA@lI@oW7#?^-cS9z(iFyb$j`chx^l!U6SUw^~@0(7GM0D=v)iWHbwapWL zVY5oRm&eo+R*0FX>nzAiwP6jTJhwd$%2rKWzw5<(HrlCOAVcqs&mh5sJvOZ}pfEqA^E?XM6y4*>b%rXD%&6&>rMOMn;N;ZX6q7e9+N_aO;JLdd_!z z_AeM)7+y3^F4@l+w2xxb=M*k;OD?v8N*e#n-OBoVM}H|8D`nyqFq~C=&e!H+TX1%G#N+@%b60p$!i;VxO(#J z`5V~_O%D2~?OLAJ+tn>m@-xaC_doybiT&IVuH0Y|maIXU!dcXqi1*}OhIpd5`b^w8 z4|yuV5*0;CRDA}=K_`5~sxHe#b1@52^HfB);iK$>d1OWNxFWK}%;E$m9JBF>#lXpZ zHa)Z`Kk#lVhe)d1!uwyZzhefbLUop&%K*`c1myBi?; znqfk#_2ZM#!==6D!|UP>$a!$2WwK(|QOlvy6k$E+FwFg;_$-YWBhRR#p4{kN3*UsD zjh#Qig;Mo&9eTB|@l0PUpsgc=@mg(LmQ@=JvkEPd)-pAO=XFAd?AAve7ls8ZN{lDA zaLyrE*n`S`M}GAdp?~$STORT!S<=Zq?UN*5i#&fdt#SdIV1-owzP@=~=3urKqh!+g zc;J4Yw!VS)d1~Hyu&Ff^F>yAMYvB45XE0NHyn;SPT~)1yFCG6!@>ctjp`@)-FLd@E zx7}TseKfDHfo7^5|C>sKAMCR7o>UQ?vl7SBIv@0?563Y52s+FENFEaizAhSaECSVl zN-%GDgWI64L6T?I($|uLT|cR{{>gl?8=(?jDCd`Rk^~cv3tn`deh1GFO)Sda{znFz z6^Hb%|Pe$IA=%JU{Rgj??`Qu0J}v)pHyze(s*Ei1ko0c`_Rbd8in-` zVdrPP_#(#F*0(gWJ@hZ1FqygKs^GzG9i#-*~ z34`pws{87%kGjs3R`S8EO*r?J-nHxT>mlNG)7|`tnf153qRlS!-&;c3CX>s1`g@wn zU%sn~RTTKb?;?q{o}luWrfPjcgKyJTnD#6UGH!IOW`HKNwOf!rMU#g|L(4G6%fNIc zY^p^zsKam(CT}n>vC%)owUTC$WZYwB{6En_FX}nv<)=cL0~>2hLz2LG9HZp&(L*W< zDIQ{gv9I8KV`W3>trXl!=e?#v}V@+Oz^6^{KY&WGL5f z(z7Bf2svRoQiCvr?zaoKeL2v}<_V8Ej%RB98Ey@N@3Cabr;FBqe0o#mXQ`~F#OfZw zZa*aa6fW^PbKmGbIZypX?_@4$p088qU3u9dPHIVR ziB0aGmM9JExr+lySFDO1JdP_Y|dcp~-OZooVF;30=mv0BFu>FyEeEa!2o0V5ga%x(eRZ;-k7DTM5+R2GSd*~KEMqIb zoZfS;QfR*3HOw!d2xAMhD~<0a^Zf0@G1JCb8fYnDe{6Djk!5@`PRE>I4UA+`a$6flD3aeZpOm784pZeGOp#eIy%f$^~9KKzG zX4$(4ir3IBwz0n)Ey~cf&CV(T3s8mkzD%?68Lv)x!r&cK0-#8;SS}GHuYa61y}*ci zp#uTpz$G`Ey1b#jg(d@r;XDe6I)Sq5;j%gB($QtC)y^2x;rLUp5y>on#IBRpFjqaC zMJP>CME9rgSCjr+KB)}J#)dGjD9`6VB(s$4!+&ZygM=7b7xS{9|Uxn#%Sf9 zPi(iys+!qycoPv8_H5i>UYhNxe~517pF;lbwP(C9S0RFEyZ$)OV>}dcDqg; z2$e76Q--b|0&PG;2JNQm5k8VCPQc7Y~+Ec)_3A8OjP1G4;=E87dz-l^zn!fNCxhZp(oLKdL!qq&1)uIM6iPn!<0c4vUmZ2ESCI-+w|m*FI3+f zL}-U{4f)N#K3wV>JL$Sm1VnwYHXxi5+Rx1|?_VqZBmJj&K(IIyoB5CAs`7BYcwg__ ztFkdIYeh4KxFv4G(BgGyV_6r$SI!hp5VhLDZZ#V$mD@0PWN+q4zM|_p?K`ZBb;2WW zjR`$2!eg(50zblDBzI0U+FSOfH_sqmgC0|i&11TLM!c71J$jh3SoQ3+-@B3ANO(lo zzJx$;h=b+g%1ULJMYbylJL)kEQlZZp?jjGL7cllQJ{C#a+#U(C!M<$%+5PFzar?;n zR{iGHqgL~hobe5!z*7YGQs}Cat&~M?Uhr?t=a6{2BhS>$^vJkQ_ZH|1?&h|aFL32p zi_-ncMrz?j2C~z=7D2z`Ynn4Zm@;E{K2c!2|HK0)yLDbpDHOtK~}V^LnMHZ%gUmUf*A5)|J;L z?3OkenX8w*=^#X$aFpDfP2iCAZiXO%kd@=VC@4Y>+0n7l0pEBh`6=!wrg1TP`L4{X zMErpX3LEv(&E%C1Y0-198Zfjo?Q-X@{d}`;@q29AjnZkD=AZqKkGh^5cc7m%^!S{A zt7PtxBU(=bZPw0nc*2p8yhS5Oc&OlfpW(j1G|14XM-En*05S=G$!z>j&k#F)U-+<$ zEF}i_A@Mb(hNHMHL2umP=TKW{@qB1eDij900I#-Rw&WL@^>#>3cv@s61q8jwRrvNs z3jnk#Q7@%fzO0~W?A@(^XFHZTdWji^y2j{ z-i@u?XGnFSBjWQIAsvi=5gaC7t5PK&=GHfoZVJ~=lWRgYdF8>YwOU&b5&kf~)yG$d z5zw%goCMI-tm(_D$wL{psM;xTRIap5kk{6UTZkLonTdPKSaD==ezgt}*%j;~Z@U5< zx1nq{Z-{!;BJ+U5cq}*k?XlCl9=M_i!o9urFrloDTDKYeW*FVDI9}n)YFk%Y&i^@M zqq;*!bB z-9N1?+9HZm^R@n`WgD$h+|}S59(Z!CdM6B)wUt_^(>npF2IGgBBu4pQ?wyLw#z8BR zt@$R`&mMRQweBR9^Tf-H=aTXFUOX|w?^7VkpDEFPnl`1kdHCYEVE3s)*OGO0{k!>e zrf&_Q+z>rO&(tP}kAJqCfu4ISvdwj(=R~9m;)V;NMjrybueBbK5_@io&;KK-wjz#q zMYj*Xem>~HY=%a*?7(FM4wMhu&2_jMW;wj$S%MydZSOvziXwODFzJ?c?g&&ATp9d8 z|1^P)e(tk9|Lm*d(v?rLz$jX7%^+)|%*j8l?58~v#bT93zCqx&%?doXHj{{PnjU7; z{c_1d>CZjxw2X8`vesmiSVhU56uy6*6p-}jXPGkVMS(uM=?esP+b55u4_#SrHfd;> z;cFG>Yso{*!w;dW z18ehtS(!*UP;|-gvN+12foqeSi&OuJ8SG~lwANVe?UTJDmXe)X@d|pUuS(~4n!dx* zNr{1XSP2AN&fjNNQ4}iJR-!V!JO#_$Y0Vr%%+}2n>J3O+YNa=vL)_>}WSxy<`&PJX zN~*Cp=w;IKP2Qis4tj4-R~2tlFZJTnJY1f)kvTR7ty9P_D~<%JS~LTMOi*9|K)P3g zH_VTAL(WVu4sqKPP*Ki{Tlo&)hXw468OombnVbl`}3g zaQ^hKeAu!AfRy``++!*VhoNm7jqvC3LG5LL(`cCZulWF5iQyq zAyIyA4N+cuia-?GK@qn26i+yvmlVRDEuC{+3jIgYsC0cgKR<2r@%lfK^PR4gsQ;Pn zM?TqS-tQ`k@FD^Vlpt1qr>ygyDlO5b-IVegVl2pIL z$Jut4b9SoRRiyp(W&74+Oh&5(7YpA@-|F8* zcDv~+Xv;m=YJ%U9=xMLLYImY{RoB71_3_cUX5@TZk^cAB4~8Osc;_&^s9KSI0+PD@ z+uvwbUBDA6k2g9oJZ+tr$d&(4+lkv*OW_;;UAa5JRswU^<2C$`#0m;JsZlM~xi&A< zk$7?hyZAoTWqMAHU0x;MDrPep?pv-MR(1f9TZ=STH~cD$^Pl%2;e@Ks6gz#%bfjZ~ z?R%WXLvFM>F-8HdWlfqrUspiCXtyoIrZkBerQl>;5v8JS)3Db;d@n zK3lxQ(eEg-@k&6hK|P)|)WT)m2gz1&nC)-=%es~Jgok2&xIi$0(mSBe^xtsii-`CSUzUMw$>jTK8*8&?zbu%+7a>Pc&XT=y z`he5&C?8K4KCs2c0a3jt*AOdxpr>JFQYgg1+B2@kE};-DP?xGi*MJiGhKc>U($nSN z<1`8MGOt?-ynzvQIK_Jyn{eqqvrJ&1tI`xFh63S?S@#id6F53;%+^IWh#PDlN7NaM z7YrQF<7USRD~}@@kyDjWy$B!9(^<-!!4AI7{)j77aclflDRq79$`Uz!O<HOl@iH=WBaYmLcGl`O)2}PA@+6%tyL_F%K)RrR}Mgw|1)S zhqk$FXZSX)VZT)KeLikcI9FD&ZKmXVew4dNwBD)g($o8sX~o`=Y4e5n#v^ySrdC?l zi#`OIvS^|@1f|5`peB6t>%|dBt*I1VN>M@2pYNDrhe{LtGGwVkQb)IQb8UWm>*hKE}Cu*p6g4$NgJtoY4(1EHD+c#5#pdGCNtDcY2 zpYS;s&F%A^nQiz2BXdlJ|FJmUNu`$SL0j`q*kM zH|E!TNs6X)jrp|!5HC?PpC@#Tt2U787Sjrd*q*rL(>uqk}zQnzO6204xYgKVI*~B557$` ze&B~ZHlE+cv8Lwc;Q3&k&DcvyyzvrbBVyQz!$@6iS{*oHE^uVbVL)&sN+M1U!PI&Y z5r<%@NiTUE@c4A388@bINKiN&^CrI~wB-r^rj4O|um|*KoI92_7eha5ix_hl&_=&A z@Mghkz&~m@rdcZwvF|G0nQ(LmK*eYq4WqEIA%4>a`0{0Vd7I+Wtk^{%2G0`vP6$Q08vZlUo4u3zgY&-uDf4Q+)^^?_G0+RY^rs$ zcMb&8Hgaa1J<8h~N4M{d^~6A3Uy7X89-;3=WiYPo>SK&@uP;JYiQZZ*o;;m9oHxq` znMP$3+feOo|Ko@OuL;UKQ(YU3F9yh9M`ye{~xq=u9R>ERli{6>}LR4-umQG~Fl)8ySG&qO&GzNDJ9VuK5L z5w;7tTwrengt2$M#)TuVaZ%M&PAnonLb<-UeQwI6FtyHO0zdqGfoNC{zdH))DVac+ zg5ew;nVL%#{SRa|hmXcfID2uKE!|T}0BS`01!u!cjF#m(=vFd|2grH&07TZE`^{TUu?J4 zy2ow@6fKqR3CK~}*rM(#*pzQ3tG4ET7Od)X3;n3LJDa=C)-|qu>bf^MdBolOe-h0H z~fNhCmgUMdN_gSU!(xp~w&H&Gin8HgrLl5}gfBKXgp9V`4nOi48XnVLe@Qjcau zWG~^x@-{Z%rejilGx#0T`JC%>+Ra*wd%y|5Tj8aTW(X#K9p$X;tk2o@ABk?Xv)e!o zctc00ynyojbFb6TEpAC(tmOLJs>O^H3*M2rM6EwJyT>8zc5)K?cMj`i08M4(X0Ed3 zAg|0lS9Yjz2oR3i!6v?*YBS-mEOOL|7EAuk3i_IhuxjC*f(OZde+~8J;Vb=h|J5Oo ziS?MH*%w+EV51&jY9n>%4}&wBYHd4a)pkaA?ybEpwmyyM2P@ zhKT5QogcAUVtTuD7vQ38qQ20n%d;o~Nc79`Nm}9B&AQftT1j?5ZN8@5s^`DoxB-y< zwdugfA(Qr|#L$4makZ!OvpUB`gp8xT!FJf{F8i|$mB^5?PdrXcDN>b}Wl$N+<+q6d zS6NrMl|&B+vN4m;+~bCp-E0q|4}2^9;A6?U`(<%a9+%3z)E!o>*Z4-&WnMl}S4#!y z@!T!mk?J7tNjp<^d`T)J_beSu5W-N0+;FcL+}j=R6TQ+ms1x9_@vZpZ`oUh8Ka66| zYKmp*zJ2@nG-<$UFP-|Ij+ zMfD=Ny9_}4=evc{OX`NwTXAIj@5kBD`p~;0IIo7tYD1&ygKEQ0a6p#H0DBP#Z0X99Hw-O$^UwjQN&+J!BdFF2F(702sKOD~x%frA$m z(JYGXmv^hAbV_NuwQ_g?2CMZGhsyuw+Zy%PE4vW9V>RHqE^ry3vI!{l9pRMl(48#k z=gW6c9qxGHQ-O(#`VCS3j$`On}c{Ex>sq`~=fgI4Bt84nZI(w@A^~cFyZE7@&lA zqV5sUO9Im?fg1_GW&BJ?dmy6rbCcUR^9&vZ*q{U$ z064m}GA~}?LOcn9_Or@T#t~u@)Nd!1U0;4^ul{jh9B!?~32!C>6DGGd<7&T~P2Nvf zpwNOZfyKQR(=u(Mo??u?pKffec52cO?Q4jh0&dC;G8dY+vDc4YayZTWdjPe3`M?(V z)r5g7?S4a%TDhi!pJdE^Hza}}k$pGv_fk+=v+t5=YGy>qZUD%OmJmflIDG*$BxX2= zZGlSHrptMq*yH`+tokA=_BwZ~Sfp}-UD^)UGnvn^k8}4C52x?1sW;Wq zZO%zl_%`|tx`mgV-}+NuRN-FWnoZq|PySlAw?ym^JR`mZY|fc%{v`C9G;Iestk^E_ zvA)kK0AxSbLM9i3`BE@reV&HXdaw4+RV6cDXGq=WCIg(*CJWonB|eZrYeP(f{M#0< zw`jE^2sB4K+d2fO8Y%i=$)Lr(_f9u( zwx`&XvJ#GHfx&k-!**wI3>~n`iLNe=7GuxfUi#5b=}U zGz+ETdjV|<^xV^+c-d{J;s`a zQ}d`mfhD2G)4>rKXR`-Sew#*Uzh+F-x{UwEJ{}_M>$Ab`sXB40{Dt!A-F!juA7UQ{ zfL5vejNjG-&8XoGnt;6Kw}=G#CszaVuDiC~x!nl~I~ zv6>G{-Fl<9e& zSwORCjxOnT^|V4Ut+qoL_w?g~@d!3P$2~ap0v&X;4gg8{PoGUbi7AI*5RX>S&I!lf7c^?^p0uZVLOQNMYSden?uI&Q-EuMNM@QtT{+0BfW}?jrZ3mkR zY-cJlNlF98Ox{(b&>TTEZS;|-uU(tDovsUg0=Pu5Hx~GXm?;quu=!&r7AQs%oS~L8Ka}JY3BZ;Jb;Qbxr^QFN~8|J){B$K>6v;=&dM2Up$9@;?tz&`;~ZguG2Sl25tq!0FBd-l!AqZ zi|Z=gel~vkr%D`<@H4~A7Wc8+fhsvAi_&1(kU^MUHysX1IR#t21s}NQ{CI%!CYoB|KMf)Oxkn156{?y#l`=*M0+fE#}D^51}8mNeU_=*vrLL*R6cl=Qtxcu z;Hu;nokHvdq>A+MG1aHp|4%F6_;fe&k*;$C{j$o-NIM=GN(2<*dOL|eotBF+Mm&?w zLYdY5>HTBu5*u)=$oKDTnW}_izQI-v-~`@b8h~u7MVXvOfP5mm36auA?39IEo{|5YhuvG=nS2sI^6NS`WVVdgn@){dYPoPD?%!s4 zcm>Yv?r9y4h6w!c9X`QD=y%%hM;_9jw}aX)sUL;k@4KZOO+IP*_S=GLl3UiZk7~&d zlFI1|(fO~UB_BQil4O#i4`}z#0w{UrgURj084}LN6H$Wqq*!M@>T%eu2&JoUC)=$QH%RVK7i1|<3~Y2k$~Gtb zcO2qc-5bTcWJ1<3bGt4Z!v^2l+}c_FNN=iD|I$9vaAmDUDwUZ(|6BEQnzK+1^xKG( z>z_91h3J(X9pnRNMY2`vK5^y26ihwNj&+p0VX%V?GuJfn*hX%$-=~PyHNr$s8=tI7u0( zSY7DlWAu-nN{jzF0S<@=C#pf(0Gpvgb%DLeIeQ#XN(&oau@yfBGtkP0nEFHEd!W&e z$gaIaH(h)1TTt$bu~_;#>fH*uIYTrWFv__xJ!Z9Tdu98(p{&XK5L}3WW860zYmwfS zP`(97%F4ZKl>1r^`?nmy-zhD*JEzWy`0gE3^-1F#kCle% zR?h_#v;;+7+6f~vRJo8ac9@oX-9~i7_UURp`sO0Y3D2cD!p^_*kHt+ZAU&?VIXJ1syU@MiTPSEZ~D zMTy(~y+3)M++hG1?S28(eq;Cv+zR&jWX^b?!#k&qy|vC9jSb>eS>{r|BPk?~dS-63Na!ZjhDo z+IUVDyH7dRp-eWZ%xu+ey1`bF;Cktg0fn$rEQ}9m-+UTRqM)7Cc*NY{jB$jb zKoSo{fX(z3=dSF8_T~06v?O-Nv$LOKOqt-tdvX-r-Z>wjEpDg|F%tBsh8%}EWd>(f-+Vqoi>CrDL-dZ$QH-~`H3KN6d@6zwdGhlZgjP-5EmP`s(qzikbGqf zOj65w6?Ar0x}L91+YUr4 zQ@aFF&w#{j?(O<<Tc=YPUhqJzu4OUzcn)W|NXfX z*zn-}6w;6b&^0^q>uy<4NL6Old?v6@T-<{%#toTjx`yMXl&JFP{Qxc2( zj!VEs`%Pn5DRf;qBEU3zb&0!dgV(R0*H9lMV*Tz&w)>$z_yDIr)HG#zakTz6(sjuk zquY(pexYP%L{r0Dc-J(Z|6HJhONpLVm?ll|gkBg<)2&v{98uM6aaMf`wV5#y3j1Ru zuT!C`=6x?Td&YN#-xQ7563l6QmXw**l7pA@S(MpcxE)l=8MEAvj-pxxT1*dD!r*x!y*~;Z@3;nO>r8$^+txBkoRA zgPNFtb_}GowF%;CF}PkUr;7$%LX+k94JsgDalC|H-Am?rJ+D!kZ!QpDk;tZInVaM4 zR6Qw}?oiu7zmK8=2-`{G#|^g8J&s~Z;T;}$%{G*M*X(X4cgU(;f;0tZcp`Ypr)mVy zI+dlhsa5OaKCw^u(-W<=1Mu+)(!<1c_9nK3%4qLM5NmCbX%k!%cIPtGNcQDIH*0QPr;0DkYd7EYJUd}8bbTF64 zbWwKaSkoYK1@A%J7r#E_?b1zQkTdq?b~ge47PB(1wO}-% zk65DSq*!~+CQIUc{Z%vZOvI*rssfT#&BfeH`+bP6yS=#=6n_`FBEeTtBr>M{6HAC< zp1e@3lkg=&wUw6G3J?5{ogWt%nGPYprIqW-?FJq;v)cLkIa@vA-T*S?%`8c7pG20* z;IsS3(XKCdBix|b&d`c-T6FDH3&)6I#M#;(X>n+4)3*)0O}Jodv)dWR-zZAc>}YHZ z19@fcQFG|Sgpd9dRO(#~<*Kz|)_iuV)A?j+8vPx0=?Q6&vsw5z*M!`mB~`rv^Y3(z zB)IosyZ&h=ygORi1x~y`b=c6zbXZv4%D}V(m@{Xk0&#&lYJd*PKqBZ?2PdmfIcTLU z%}yc`fOW$RJ=$9E_LnFoCfP+1hsUo-Tz(3b>*w>yh%5c5D6`0T^rvXKSmC)&hk#r>t}hM7P2>3V-7 z6Q~PSe(H+H6#7~{We)ht$UgWWu47Rbn945*4mC*l)~ERzd)ji>k0+#@EK1(rnG z*e6=RN|nbGqg=f$GDikbLf(cSViYFg4+$Yop9D^yJ9kF`Lj(UFh z_2KCSpB(rV`yI)5r=*=DTFvOg2+kUq5EZP2+qkbd5VJD*EymMkrD@A!Pb!rMA8FO_ zc(pSq&EHGEt!7OUO+L2h4+;H?Jb5rMXTlf;+!h``plP;U6uAFQ=bSxqrUzlSo!Ug- zqi; z0%R(sBp8x&dKE^IE!v4$A?+r)WQ!$uEdfga7uav~(Iku*7`c8nWqmvFO1tcPhyct! zs|{89+|ryp&r!ksy41j)CMBQe8$5I+tIEoS`aO^L$A0k;qSPUuJGHiDru5^RA^(+x z-YNt?tYO|*s=!o%oO{aQ>_yAx6(V`UTWyN2pC%{rr~5#bWq%H=Bu{yw9>&|$x~sRC z>on}B-(^3KOwf$!Tdq-N)wQhKf6LC_DEzDvxUtDvhytT@vm2)LzXNtmIddsj33RD$ zTh(m$*b93t%b*q4^+%`tQhfqZBa^8qPQM~dd&h?;yE8@vEAH%wA&(F56in;7Zx(5o zn#lzR_}FW_in$^cMGVv}?0*$X6l{8*#HGjh?WI6_xLX_dUNY9&%E%&!y$M5GiB?*R=;SG*8ppEszwhY2b`vGpfUp*fJgm%?QJ;kf;Sqq-Kj0_*?sY-sNjcIJq z*sQV_UTyBr#QeMc$f@Q_qp-KDpg zM76)P|ATgCx9@5IZNlNIt5Ca}(Hv3uW`vV+W`!s*M^Bac$I0l($E!F$``D|jnCg1^ zOGnFr)zr;Q>|0rqcxcJUp#tz5o~XqDO8^CVhIo!Q!o}Xk4wg++0;Pb5{l4^G`*S9i z6Glp+hJ~iTTgryMl&!G-cx>z^=TRVg8;~}Rhnbi^7vQ3m6f&sh?d%Cm(JY6;&({7U z@hi2NiJx;{HFDy5(5r531imyXUQ?UR&Muj2m)s)I^XYIER2&X+eL+1{HiNsolPsuw zud6{B4tg$QnrGMMLJzCg04jf{KL2)_-ktbHO4x<6mO-$`rz+Rj^nUYXrmo1y;1-gm zU95SkNWPZqxKpur8n-BUiXXNY99>yil)4kG)+@_d`vqbyS}Sm=af`p^De|fN)2AmW z*XO!cvI-lV+P#hkzh}kNe|(;1DEp$~k<__%=wOPp1XuDJK>{E_V~*GEoSl|^4qzUR z5Z9A_#k@ag>i}VkRQ+YkCx|f|3Ezgg`_q%pmZXHi27E zkLYnIa0X)2O-N#>QjRmdDkhZt@_96<#UlwtW|n)-R`m`vL5!e*8wNxkYof=X;RU0P zT0>*!f&xcV)VtRp$R#B8W7C?(&upy{enY-Ca{LGyPqfor8Ll@siF{_C=DVq(`hU|#RU#*KN zro*bCUIV?AV_W(1^Bj9fZh_KnRe3i`=lyJ11C`DUUClm6&k0A@N%3RzZUfnbCKy2L z1X-{88fdj%lEG94KGWX zINh4kGd!{DEXXs<_H6D-|1zv5>~jTHfuEO{+AwGwu5;gpOof* zQG}_=aw|KTUd<_YJ3JZ{On(dJ@-gjOGu=s>u1Ts+Wo{8@qxs9ek6nyTJ=AU@BLpg3 zaz;IkHa;+&i2w8L-=Vwa2Oahmjy1K0TNa<2}&$`t$bV57zu48BblhoR*9&myia5*~!H02NF$ErF0L(X!)DMPn?pXe8@SvtM^f4FXyocxkZ& zf&};C5C{_7TdcSQ0yJpRlHeAc7IzIAq_{(I=YDziFL*!fPx~LNG3Hon&3Vr2JdPGC zU1X=|nOnzC;JE^Dr|%+At8B|QW%$O}pu*NL2(Emc@DUfo`EV+##X!(i>dnYtcIZ#; z-Gl}dWwcm{%WBQdgJ3FqcKT$;anYdpTF@`y@X|!OjX~Y;K{T#ju@Bkh>h9H$Qzul# zK5v2>be%1&(osym{yi?S-$Gy|-QsN?5;ss_$+bOLCX0(|%Oj62R|^*6?qhiJ#Kc_o z*H6bmJlZouK_Cl(QsT)EZ^jw7^zG0jtf8S5r_LEVKNDIy$7QJwHSXeA5)*H^T@Y^} z3e`S5_L-@*QN!j%OrDaq#^sFZ`)}kob9&yBrpWLsR>;yDy9$DyB*q2QkyM7f;@U?u zj}-gaJd})+QXe9J4^dV2q{dK?YE6&y*zX9D+{?`2qp3^Y%#NNQZtg1={Vm@wHohY*|`e$K3n?G9HjNH7P)ctw5)dEX{ zh1RJiR7T0a7+x9e;pqKx5w*N(C>N>v^GhN1C)Il17eoyM=Ecn1Ap=wdO5s0Yq%ZJo zEmMjShTN8UCB}yOrLkoME0iQrQH8o&S%vj4gPxhIItxK0g_jbKNOHdg6N(Yc#dChC z>d<>d-B}snllwg`vrZOmDRewPVQlOS~>v zP(B!_TT=rxc1i2&t4>pxqXx~HEOsQ;HXn{IO^haWO0$;s+Cv!A>>Cm7!&d>B(Q|(1 z8UTl_4-!lhX51&s=0CqtHkRJRK1cGNP`6RuqqP$ievS#2CO&^p(SW8FmrfIjsiI^*=#9Vjt?t_Pr=`}-?fEr-Ww-vr8m$E@ zE4jT7tCQ6z?L>vW8UDIkLl(SS%CH{Y!;Y1COM77L{kqlK69(kGg1-}HU8&8PuUpg9 zS_AP3^c$I1R_e(D0JR7Xvj)3-PvaERBF$cy(HH-#N3m*EA6DaC6WsHn+#bvz8cLqh zJ4aclN=DJgf5<});rhs@#X$*>wnipF8`id+dgvSD?PB5PiQSBO=&${N)=2dH58OJg zf!262Wp)St`y7h*;r${%g!n@i;}i+{0|mc=+0~IR$8SO>h6P-h>}l{2{78e^f^XED zON_nf)pSaNaVGa^`-V~#|M>)6{7`yIKdinwz06Y z9&Z7AucI0*@TRzqu)IzRUGEKepguZMbk}fll>J}o93q?<(C@y$`6M*i`jOC9vy_}B z2802OA(L}rmenBjLggtU7fr6Z#&Ta)|F_>xbX%;I&Rh$-=q$Tza2YMGi$h&Bh?(nw z#qzPgn+rS^TE0{vdk6hBd-`^sI}w(0D|Nii`f9CxDLf}F#BwM<8Bc7vwUYd}6XO)4 z%R+aUrraMHrMim1f&N{eaFas2G%)LfHCkyXlV9T=9%5M@zY3Q6-N<0U%qhmqT3$Q4 zG$OXhNc)0)BgkMQ#+MYL7H{x&7L-cRe49!>stJVWqB`cDWR zqHopXbJduWormzQ!Y@w`i7JsK;qPMiw?=G6qK;lvd}hd2#w86NfAZjzhQb1AOC!=_ zP#(e>htqcV{GRChc7xWS(Yu(dh3`mOOSgM3*lkk7-eGNcu<4wjVqMYx%6nLD=IP%9 zM=?uNvloCLA7>tZAJ7_6@%r}f+klESjojZ|6}Xalr5c^6Uz%1yqP;`j7^a5p9?aJ0 zTrz1JNszbC`M=zK{3`^IOS z=EpWb_iH^WF=bc7edJapA06#&2XrYX_7NVxPXdsSM~xWe&*Q$+U8n8@Yr_q;?p*!7 z8P1vvj+-v=*3fe;?fM5w5SZs^4QGqPGd zXYqhH)Qjul%IeePqy-yzL4hYuqDU6)$>Rm1Uoj>gcFHeZH>a5p;ku{mS$(;QAI+H= zdtdO-ROJf(4K-os7ki;P6akSJy%Qk4^6S})M%1tYlbxi*I)$c0BRNCT^J&>gaTp-N z{VIV7023Ndlf@o?ciqlhMmar%7oNs61C@rA7%D|a1d7{+a)E5Tk$(yp)?S~lJ%%_- zhB0#()1;A{CLb6`js|jD=R=S#XfSYMO;V)j8m{3|Xjk~ZMfH{RB~uf!{6fQbQD5l2 z+*x0YrYT(p4vIx(*y$4#+9~?O`xr|I8YMWx#!vqtR{xE^-=aKi&C<_S&Hh@YlFX3q z-)}zF_#ga z1nn+sm#hjoZ)t`#D(d?Dy)lA&rb!*2w_Q59Wot*G1XN9w!AqHImKulIFC=07+MT&LG%ETMjNX?fo z9OZl%l>uQHW&+{e%mKo5+kZ034|C0jjmo{0Oe-~gS(x*mp)f2Hr9(;z`0ENhU4Vj{ z(kUWT@!z8JgI8+5kUo6=)it*GlLazTCWV6h8#~0SyZ(Xp@8}J{2yfAUc@W+zO*xC* zNb(mt(&>>5-r+Fbpx&%(IFRqxAW&79y}C3HH8D}#qhv$9`PGG8m!B5`MAj^JN(utwjPufcU>H0}&f3Ee=SURS~6 z1s~Zf#7ad3!xfufI(G#)cte1q7*}9oL#b0{jj0j!rBhUtySw9dS&a+QaZ9vIsW9tK zqIhS$D#p-~=guM9Y?AqJCseg=vk@@pbGL=;mU*2Xt?ef1X0BfK?Qo;=!6%h|=DRLN z2bE+876APs>mK=Ra!!;T$NfsomO-{Wro{3}R$_S-2+;TcSByAj>-!>HWGafc>)SO$ zNJjPxKrF@NJ$8^F>2*MQE?9sogp4UQJo#J5k7st9Gk)K4G50bMus(xaLk& z=S&dll0{5yPl8A`v7PjyFVT;?^seaKvM9V5ohYoMeCpX^B1En)-l|NdP75m0q`K}Qm?wi*aynS6{UeL^!6$hH&Heny>AFF z09Yn=RLv0T#2ln)QQlW44+jM#f>fK&U4D2D5jS!!C+jARN3X7ksz+e0<+?jTgE_o! zy%-wQQz!p^$J`3inReC#^2HQA7CDcFNf&GGT`5)I@jje#A2McbMX2hgVd`0gU`0<$ zD{T|{(R~dRwPVP-Uc@;ad~K4A&k!?RX_sfN4}F+C&Gdloo94c`Iv~+%S0HH0`8RK+ zXoV~u3G;h-Rfa4yYLOc55(N=(%mk|z!S>4fZe!XwL52W>>Uoi}(48~sjJWRj0QXv> z&Y$xd10wOCYv*PuN2H+dtBEoS+rr=%AAB$*a8xWqFj2Yfj!vFY=iC7K{9jE&R`@LI zsN%1|UTXopru;03)A3Js_6BeisAdSP1_*t)@VXz z)M|#qGPzW-Dj!Q}U*FS3SQPnV6EDvT*71?AT>eiYTz~z(qOe}E&Z=O+Qv$BZbY&s- zGQibiIM6Yu>3F2d(1L6=Flvw%^M9@~)O4kd@_Z-~zj9wY+Wxy1)bs^CkJq|7 zYqpopCP!fGRhkz4S)=M_NmrCwkF1uDtoxG@Ipp=H)u$bos97AFAqqa!g+&jJl?i(^ zG|=zdl)8O)_5YqPYd<26DvM z5-Yixdvm1pXC4qDULQt-xy{P|WoJ?e{QI(ptaB+8svU#Dbdn%DRQ<-+Khz!fb8@z7 z|7AHCx7wfnd4A#~KAqldU5_r#S}9Xd}?P2;8JLXWezp!NS%}H4j z#3R4yub8X6nXasQYi50Z_Q4(UtLP*IdJm)tf+77i+fSKumba$xmS*h^;jB^J02SuZ z>3IL|nXbqs9MC5 zC=SECdIDv>7>PReB+x$Ub>caeI``D8N%^SCjRV>o(Y^VetIPN1NB{DO8~a75U4Z=3 zIsMXdHYG5eb+9=;cdI`oKIcW=7AgUIvnc8|4|DU{w5W#%Qp5 zVKg3r`Mf??Vdw9v=x+()UTfqANmv6doF{;5WxLh!B)W?i&HbjmQNtOw=-iQdAZ;(?BT(moBf>a!Z zYgKVkJ%k;bQwykJQN`vYUYiol>)%)OJ<{e71+z=F4L;J+1v!F61Jm=ahq-oo*l6lg z;Ks&>uXwl0<_mw8s{qg-X~)UDLdQ4N^B4gpNsy5PeYo!GSFseC7t(SH8m!-WQ)({6 zLh6gW!iSu|oT|cHAU1$@HPUFoFer`)0*9L01^Hq_j{1tYvc*ZcR9JNp8_a~$|m4H5xlW2xrjMr99^fRDgkpE8Y9@GEg5ko|0 zHA=5ZXaPKAKXRYo?@6^rutD$1eVtPV0!po&p~qYia>hcHVsrk(W)tG`HH)k%RrJ+c zc7wLt0%wkt)9g7Kiu_5D0JB%LD)0EKbY4e{{(hUi6>TMNEF!Bp5!ncy&AbOb7rLi- z4)LOMJ;>9uw4nwum&mh~Ef0G|aY}AJ!DHc=2@jg9t48!f9cCqQ207=Y_JtOoAewcshR*#48i;cWN%)`ms;+i{ zL^*lU+`QWB*<=Zu(FTQ`bUqKesSW@h4%W?37UAG7WIiIbe)#1`Ry9g2>U(N1+Y7OG zPj8yU!aoaIq$a;T%^t&Ra#~IR33CfA{a`IBHaO{9nkV~%>Vp^w?MY{)7*W*>9wMB^ z6AW+8YBxR@z<71z_i27|UM083_c)-MbgQ6TtE|?K(t{PABt`kMd(gVXEpNp3GV-bt zS(tU3v%Kd0ZDbHphl0;v7y>hS>$mGVrQ@Rh&jpHoL1N#aDgM)0UnBl?|kl9IeTi7_I)QZ}glC(Z+rF zZ`z7uT8$@2I188z&u5AyR28HTn;?l<{Y&hcYhEIg#6_mTM7Y9Bi|-ScN15wxrQwAI zpkbj#0ek+C!|C{#{#0>yaD!(wr{_(*6{OG`Vmx+6FUL>JU9c^CVnl7`F~e%jSCGTC zIY&#D|GacCpW@T|*O`59^GHi#8UL1NJ~ztknXY`nf0C4_VfM;yP+orA7YQt?orS`t zgiY>#2;{7;mT=Y{;Bl30+zN_qImKRoPh|uHI&$1q?yLB`uiesjq1s#t0OijtnqDqZ z)Fn(7;F0O+?u15@<|m&_iQc_scfma?@_FedPW2w-HO9WJ0AhhmpiypP?wOiy|2^PR zstk^7j2bkX7q1yd3F4i1o(?}L+tmk?pYy40V6g?lT<;y z?bopIc8oMzZ`B9MJ0l&kgC`ID?}l69bb_z4qw?**(&7kpUse?HnGQqySb60 zKM80a#0uL=nIEW=r;+!FsOhg8B&a$9fsV*X6iyo;-E7D;`*$`*xW*Xc={Y1$9W_)a zpq5|M|K=x;7Xh25A~s2H(lW^p%uJ-nqgSx|^QqKvr^)MpDvw8<fYm7#W|8IZ`KQk@}TG{fB&j*`PL13`HHsjx}u6;fKebd$|f!o`W3Pmj&s<&Q1 zoL$Hj{~%-c87)AwgXzg?5I2RHd{g|R@YGm|XJ0xDD%`fU7A9B`#uKiKlpr6Z4^*U- zCm+hXkGc-*eKtzV_@M!ECMp!UvB3)~VRnVrWO%b};lJ*nYyK%7SN=*th5Yr97-1TT z{=F|KRxB^sl+osG&{GdLU$&zV?6mnV#%b+|LiR{PG>(EdIQ#bf#$Fjo$B1(S)Qn%<{Q51>njxIxLwTM=K^8zc%DeH|(Wn{x#nmRbKF9;S; z13e)yLPoBGSWer9_f;|;A0BXK|E-E>@Mr501x^@c8%a+GgGKQG1mBFQxV5qVM16|+ zBdG!~m%Th5(ickkj(5(I7V~4;$05)6s^*#9Ni(47jR^r8A^aDxm%kbPa`f?((wp>ug)OhkKH&2}Dvreq<_&5$E@u_cmp2fn{lS9f%L#u5< zxtB<_2F z)i2!=?Rg5uRn;WL8vr(u49~B@TKV$FF-q+v4dt6}-ZZ=-lID6_o})m6bGA(}zVP#Y zIU`#@$090c^jM=iHjr|z_8aA9W6-?}!-{;$#7+uNn0ec7OdQMJ}L|~>izFB`SOh`9~Lb;bcEe$ zeo>Z!ef7YvHc;jlkJ9O_=hvqrpUm@v=cjoJ%^?h-E{pgG`$F|C*{*R%0BVrA;mrGd<7vv{Efpt~r}4zIdF7GE3StK)ZXW{>tJdG@zQ|Ab$OAHqszeqPMV>7FMzgJyB+QTf z_n@?)M$@Q2>pap>nB$YiJwMZ^UjFRFTezwh6Ogg5cIW}}KhomG8>5okppPHY;&Rr! zr^@=ui(zBFKn^NCX-}ko8x-`aLG-twEtSp{IGHO)&l_7G%~hS*QC};vR~t?U-3q$a zumkhPU}_L(Nk3tI>1}jdx(yAWA1bnCw#e3<+#ETQAcH_vy4qnmvlzSbxxBoU2D4r# z$n9?VI>u$II4~6@#&MK4(s?pIP8AsZkdrs*L8~DEV5t(}O$Gv2Pmrn@kv*ZY*-K;T z9HHbKs0%Rjt&b<;0(sWt^D9k+eQ8fBw=$eT@X}jmSrA^yhOm?z_{)d(`dDtJDqa4| z5BVo=J`wTu z)QkCgcT?y9#J0Um5F+UX~ z8vX%7fBdOsd1GHSX`$)od&r=*E*vtL8;qFv`Ly&#u1@|{S2*W3pIA8glol}JzG3lD z=C~uX7P4|XxAkHc32#p?pW?Wu2@Z5*nveH|z_JMVRP&J+)<1N}spkdd+&Ni>M&Exq zq>o>=Y;wBvw>SCJQn%z#OKcb1CIR{fVg{hMuXp*tA zc)+%oNl7O*#mBmO))A;Pc6>hIIuA<&9oaSP)vl$?ciI_`7s|N5uPw%dMlkCdpU>0b z_YX;nA6BUq9c(8)12&(go?Ts{pnBQ!mEx>$1G_TI{}pzM{0X7=^E>g&j zFM9;?7LElZ>MmhpRM>bUaZ)_jytG$JO$`Q6k3YG@KT+ZnOT7Ot>`s)0_DY^wh^=stM@s@y>>-VGLEeS8bXI?O{lyEM%Q%;KNQGCaZe}Wy7 z6AuHu1W1A0VkZIGfhnAnNcT#Du( zODKq=8^pnwTa9{5;3+3#N<;p_~O>$$FX`a?byVC0oRTHJoE1`7T`_&6Ut+)-@?i^jrM4slVc|nmQpLV>#j41W{7!aFD#!8htI{0i=57F zAx{g8Ix=?JRH7|P%`fm@MpGSsc)8>%ym42!Zb?I86}EoH%9;T>hhn{ zMR3losT!6EPd4h#lbOdg+iemJ`7P`s^jyASdt;k+q%^8=#7YBn?6>9n%i;2@t?77| zyQ1gN1P*_-2-QLm8+l+*2n35vv()fjQprr1;Fr$5MQ;-h zQrZoYsq-z-+@j(zVMeu*8hP*8OIKTK;7n}${(CTXu&?7cnmGRXQH|yLPq&pSr{NgF z%xt-%AF}aLdG^yc^sB#Kp`?J^L$RgZaydJpb#cHiBA@lD$!5uWye(x<_+3as^SCNB zw`?+z?oW&G#JKc*+ykr^EI@|spsHHxV<3s4^99m9%4qiLF3)91luMZ_xSqA37@8HU z#J!QR?)jH1ozHK|XpKoo{JoW)1GkcUj0SP*PJLR$3py$iNhW>b65~DI>5+$#T$HSd z6{Vw<+C?HOB6&IE!N|UQb7)PvS(7#+l{ZsjP)Tpm6u~^&q+b8T2w|Fel_S8l9#*#< z)v!Zn)?w(LW=Fc1tr2u>@;E7Y4t03o@ZW>K-0G*c>HaGqoDvz?3dl5uc>lV=GHssR zzBHeH-^d)@vn^Q@Ri-<{l2mv?i!Z*X^a1W%5A&^0bK?G9g^0 zMhROf70fm%|50gzg&6o=B)r)BbxcEVN6*xY_mFYdxL^bl_vW;gd7&VEEIM&^0wC;I zr#oz~hsUnUQ&;2Z;%O{lB8D3N%vPQwoJIX_>WikTxJ`!B%%a}B(Mq%Vy9@`91aP*e;W!en2Te^ji-}Z&gBasO^kZyTgYs( z2FCK)0o6%nG(&+z@{<>m$s51^I(%R0a(@}35FkI2I$%CZ@g^>2CleoE0mMl1(9REA zgON?3A&e@}SOKk)z(0RZ_3M&k>$b{#PYxJ+g>~$l+_KORtxR+;BHzgw@{if7#^8V_ ztB6yt?s~z_vhBX=HTsBmWqE&z(l!?MHhlwn%Kp&40=hk;9W(BO$*L*KkNaP05ah?0 z9g$iPMu}MVtbAjxHeU)X_udwBaWtq~CkC824MXlwccCEmKTCCk4Lf>)8RVQpPJm-{ zAR_IMuzVf&OVn9*!+lZokKGRbB_huoKPxYrLKN=%_G$Kd0p!Ww_`2YE=3)oZ;P^9@ z2D49j8lVK@F3qGCBM%@iftVPlUQ`TQN9Cch;GaT`%Q!caHGurNCt@rG7hPH7>R`?` zCPPzIs{h8 zo;)~_mGi&51=MYGKoeC7rSzE#e-{^_v{Q&60Yc}wpVS~2E){yFFz9v1LyV!Er=euZt5SY{p=iiwt4EG6N#wu?t=#YrMh4LSbdAtds#-!h0!U% z&E&b$HxQw+;b(_lV4cMrqqJZ^-@G?-OZ7j?_c$GVnu|KrJ0S2KU*X|Bl3N~iRs)oy zzw9p8xj6vGIk7MBRkeZ`saS0V{}C`N^JB%=W*X>no9Aov=?FxB&6{maO!9eBT#mFd z={4_7jlvpTFVp1rRFjx&ryNe6YTx4_sQ z`6!#JO4MdzSBp%YpYY2phVri?!f(^Y4EVmt5nGl1_aH&hnAja-Y*Q--B z73Ug<1ouXIT#vFAL+LOMO*zv`BG{(GH3iU%Q5}_er1fxF{87@e5jOfq)H z5O1kG>#-*fYWy@q#2qdjM#!XI9qPg9&pjx#jSnV)=~SL<-wZZ&Au(ZTR_!KspOhWx z->6pDr3GHTT-zEoSqdB<_i_PH%T`BWZea)?(k z!^}bbjs5&(NWuuE7Tf>2CjzTSJI_omM zUcZxVi0j|2O3P*=M^1*#@hLMIbW+Y@iibn`jd~`%RAeIoB*}kV=;3;>4k>C*5`?c_w^KT3^&u|B!m8 zf_-aX=_D`f)2ypb`(F*p)uPMZmc{Nuh6SDrok+)&%-6?mHxohEm))u+-gDL%;Qj7g z8(>wV99sy;uN7vOLLtFA$K$8_@}ycKY*-oUPxX0EuLmbs{^*_)eD{14=jJ|6oTI43 z6-6C^%5GDUvmD=e_YVF%H?L+Z*}6@L?b2*hjPlw#t;QRLyr+}IstVZs;fgk@%x6JggzgnPHs(|)E zaW`gaP!rPmY%gI{2tE$-WzM+=FDh@kI^z6sfgYZIQx?w)uXuxMS9vldAL`7z8%MjO zk)G)9WdDm8;dn1HFsA7?u06IJ#+&GNt_c#=g$m>R-OuNn07jN6JVGtM>iQLL0EX_TByV=|akJ>-r%ICvS zS%q2Y=|T_qLic}_H@IeT)bR-%7E;b8N1KdgdQ(=>bwSV~Z57BOy*3f^)eKbAVi)0Z z(34O8oPKVhiNmXpo<@4SiioZ~+mTlQ^=Sg~A#2fRrN+w*$J#7DFh>sdf^qM5s8GYL zc&=VLvD0LSFJE4kNBCPEcqDSUW++l$9s9&;M(lb2)n zS}NPOf+t;v^w!e)$WworJp#0ojOR^f^XO{ug-GSWd0+$ImP~(ObJ-2ic~gHgbiUTz z-O#FW5o+u+nvn@@{Mos1z_-}?6Jyd`y!2C|Fk0LzQ1ei0p&}^ZV!n6{sY_?2tj6*+ z5*yzKr~9IWC%*zu>Cl(WwK6N1WP9(v%t-YLR6!9-gK;fbfCc-q(N%$Nx=ICi>K#ftWQ&IAtg9e`bZp|c5H|(GSK}%~j<(CKwav>>l?kC2yL)--7 z8ap+ww&#ECd|8G(EurVlffia-&$;P?%Y-$kQLbT9m56z}wH_NFlE$htLG^n|@ zl5@J+w_g7ATtP1GMY5c|uCH>f&;#?xd$I4XeYFDu0;(GW&|>f)|fm+a#Owu&Vt zf9$`<>Xl9>#R}5CFOaD->W1fIIdN3fI?&Recfxc`i9N4u4*s`PQBCNO4id zP$6ttB1`c_A57UmU)<(EF#dub(_p*Fndy1NLUI7{X|B19-l+Jqgom zw9Ta{Xe(-Sx%H8Md7Ae_)-sPUpM|UUo6^^?n8^sb;JP%Z~lldX4=Mtn^UvhRoi80cC zuP!pE;jlodgp>|>mvGKfr0h+{fhI+6#x9?J;4ue}KDn8+875-tdQSNIt$%I73%;r% zW!?TJi%W(>cmHYo!H`->dMsf{KIhL91{=eigH3eY^H@ngy&{tlvcwg# zFK9Ul-T0nxcn|uko)~Quh>PbJ^{5Nt$nB^(d9(A)VG`P>AvfBJGC?!kf5@v=|2_Pc zCCLz?H)ET?EP1%|_hn8ThXNQIBT7bzsb@ZBMOX>9L08BdGnlYn_E=ZPaQPr zZ!Y7yx1*-1iIL7zL~girZb<=1L+#{PZC5kkS!8Nm)VPVNQ%F-))oGe_DkFmG_^iy| zg1owU^q8HN*9)W39MR2L^3v+7XXx!2suzJa(tl`Gy zPMk6h?Ve9n2n!Fv+-nka36)B-+gUy{z^^v5f}=jJeIq>_aJuM-x!+nc$Nd>(%pR`( zH$Eaco*0`X0{8%=NmEUpGw^pxH{&&M%Q78YEqM*EXb{r%wlV3a6NA z%`d6+mr#8L-jQz7Ej@lG1TU>p!aBrM4A`zTEzFG`3jcLRbA9s z*yjZ@_PIs|X{0-9{BI^(nTX(@?nU%EDQ?;NxMXgCsYg$~5tp(4i9xyNNxmQ(3BKIP zYgh2kQ7gJ_=&Bn)lQA^u!%So_~z8NTJF+!l{ zkjDO_sW&l;z>59a6e0=3&5Mt0Qm`-l9@>hc4m&QPU5E3a$7$c`I3tM-6*?3eCl!ej z<7D?s^_o?Bn8I_`*kWqzx_iM!eb55*&5_-0QQ4=#%fzVv9&q;gLo#)zQyBSY`zt?G zg`r(;KM!J=`x6TNpS@gqK1!}>P#5+O4eO87ujuD(7)g{*s5GdyS{hNXAP$`yq^5Y; zF8A$&xqj|E3>UI~)(157s6+Q@jhBjB9iLbMfc%EJbR~t38KNG|t$aoA-)tGs7hl<| zn~*R~gkZCMdxM{f?GM)V@H{RBru_0@YOI!hmD-b4Geh|-*$7Oj?VO))8$-#D-0h}! zdygx5GYd_6mm78_4v#gct6MA)MP3o~_G=gzCeyUF-<0LL8>@Vh9i1RzFlZ$#FXR3I z`d9dXich*VU(2rA`X8U^jIpH05(oa*{?mzgyFWdC1S9toO)nY_Jq2t6qQ5|gqZim` z_goE1(><3(ipF9LjnL5IldX9OpBl$r^8_Nr>p*w(Ho7C!X80c=(WS4T(y63w0p)P) zkxE3+ziF1NS3t(sf#ds1U9IzxxF-2f8}I!IuU_Y>uvW%zJZt zLiH=0Q7)Gi9!2uj6DCtri^r0S8`*#LP58@~Cn(I0{42!#>*_#eV_5C){LE?Y^S{J- zURIlr=|A4176$3^Vr-c$Fw_`FcvMMc0BfXgQEkKZkAfBE$~gn&$sfNOk_?vsG6Usw zMFWs-aoMH#X8fK>OV_+IdtxjrK>GyYBuY$5^e&^;gWC9u|17p2T;o7MhG zbU|v%m$~u|W<63JIOh*5BPbW;Z_#)=RiYVT_ebJqf+I@|)+ zy{=CVMoQ4hy5h#V@>v*@ZVTGYaEI~5M5Inpjn_8>g6r}_>dBy`T1DGPVr*dTwkWe> zowujFayNg#a#KijT=uue_i&L7aQ>IvMk_TGWd?4>NKpjxxK<6bhM`r}22~0fZ{&CWZp) z76lJe8;zo^E>o8n#~yMIidg;)SKN)P0$CHr8>`3*ODT*OvX39EMt1wH%*`Qjum0r+ zWZLvP1&Cb!_L@~LvpOm*Ttfc$U?^wFo-ny2$Aixd{MzoC>i#d93MZlw4^>*@Ci)a_ zB<%9e7ahz)a;q_IfGn)E#2xGlv#bZb2k)fdouJK?+UjcxmvKxzK~gBVxo?vFaQW!0TltVRjK#fMBHXA$)Jb zkdUWaCpo|z-esASeRu$3TNp)0`gog$7H-+)2f~_h6RU61TX>+HbpJh2Ic8~gR`Okr ztw{Vn;zC- zAZ}BxEqAMXOI|hRvufJ%a&FYt&R*t=pL2Jah5Laa((d5HUu*{-uC|H!TA>Yh5XlLe z*Dm%R?7kZ6B~Zn{*cciM(>5wWHW5S&toVZk<{;kDWg+)PaTuZo%~Rs2O*(0;P+G6E zNPrL6QW&4zt7)q@HYH3pHZzq(*0l0OFzj5H3770LDar0j=#0^@Eik^*v>ik|Gnw(_ ze~Cr5WjKgvP&=!C;b0gho&UR*AwaExY1~hAZ<;f&ZJRVlc&ZlN4R6On8xfKs7k=oQ zVcBQmovU9%>9E*1%^QcY5nDcP&3A-K4#+oY+;2CFOHe)$1jc~uFXs2DbN6R8Kn9{q zlXo=$m)}oc?R)oO7!}GHO+Uu)O;~Hz|o4=6J|LTC^tY#QS40a0#LgVDU0c zRL*JlUOAOS+2kFkv0qFgr#{EImx!88kG_lx__ZRz`t9p~Ubj%uzu_6{Nm!u~<#B_3=MSIkC`4IvEStkC)M0 zK^vBK-E=K)iMp46{5tK=pFDiEb~7^$Xou8*_P`ip@_=gH&=<2%K<#)#ZIQuQ-x*8e zwy^H;6Wls-74DY*RL~nMZ7M|YS>?}$U1k&Zhn}%JQ8{y@o^WaL*n49EbeL{oYL5z_ z1xq#7z<5JjjQB>ZrX)Al0>rV@6p2hBSe_;O?AI9kPJ$YuCOjz`#sC{U^QGE8$0qp_ z>(d=-c>$s}MwP5*8$OYLqtE6vv)@pRVrW&PAF`Ahj|v#9jsGfc@K|+o`14ahje1+@ zk!2!l;`5Tl&7kn>+p9zuEEva{PU}|zE67;m-uM}g&0cAE4>4>SLTG!)m=Y(|on@pc zERORAug;=cH&hdX64MWy-D))S==k4?nAHo|Fg#=>Ay(aBlynHY6X7P>serZa$qWDY zAYj2eMt3zy%W^JfJ7-af&e&f8dCVau&wK#`v^uG6QT>1Hy;W4(VbrflTcA)1E$&*} z-KDfR1xk=$ffg+Z?oJIT4uJqg3j_(lEfB0li@OB^EgrPE6zJhQ-}y}7D|CnoR{K}u7*xIS%IBS$nk zz!|QG6M7a&LZUs$2Jm0~lmbG~YRSA#MX649`+8f+2mk{{1)3QXTvtPcTet+OY$ube zaTx5uPbBYN&7mRXM&LQ4?}BYt}Fb3GzW{VIG%3;(ERg$8m=iRFqrPDhO zJxK4|LsZhbKW@0#X_ZsQ_UlYG!kR_bEV)s>Ve@#~ypOX%f?n${{MZ!;fh}gG{gfIr z&+l{e&~o$`36b-hG4j_@Q=ZrF=~EyiQztQ5;IkPT$m31?|43l9Rk-<7V{cI>jwshh zH|r)Usk5Is|L|q~%oov+O*J`wZ7PU2bITT+c$fSw6wdvS9Dib?%)t)h?t*A}D)x_R(I1<)VmmaQ8AW@o~&k1VGhXk_5eG$ z;h-B5aL{oP?PX2Jp8Y;U1Gs6H*J8YeMnCPbo))p)nzAJA2QobQw}{Zfsv+g<;Buj) z#%`0K4d8xF_tV9Wtx?fc5g4`p)C#7=w|&2@*0t$+UcsbcvH{p2sPeN@E^N*H?Vl&g z6Ackrhrdbcc@?t0F`L(PB=Pdd=V%Yn{IWnPk>^eEpgGzz$qX}Q4f|!yuK^w2<#U<4 zh5G67^x!#u#I{ZepOkbFT~W;_3_XdN^#vw)MbigT=o9y}V09)3z?YT%HYJ3`3Z}yX zp1$hyZ@)Hvwmujhl5uY6Vy#**c`qoP{G)JX)&4zl;|oedl>XP)up(8TV+9lM59$3S ziFbPgdr%xfBOg~|`tKIxu#LrSmfY}SR?DeQCCo$p#QPtfI!KBgB-q2}pg!+mt7XL( z&tVsY7$g?$b9Hei_;PI9tr#Jz&c`xLu!Z1iVBC*;4VpzfYfJwffQ?GH%>xLVLIf0N z0~B7tR#zn_h*2`#)Em)kr*t(~uN=Xp%9bt;0< z*R7wNjxT&Ptd;_r&Tz%Jt{$jns)(22WeopR>LeUtIxF~lH9Z!W0x!$ib(@(btk{%J z*V#UH$}QjZ`hSZ=#jm*6QhwFW>h}E?AbhnZYl)NpAz0dtMsX`Hmx;lc0X!j_{rP>m zm+YTD3bPB~#?#m|lC=-yTaT4+>^5x)hdt6+rYj3pzZS;JMq5a#hqqwJcTM#jfLd^rH`$_^gOT`DZ*)gfPO)`UDd>J?8nHO|Vq0+|&3SM!aWC39Kmsn*%P)8Q96 zfutRN!d&8$xo$OJFHL)$!3Q>7cu%f_>Y`f3U&t}sd{-x#L#^igBtc%L}}$%cJAbdSC^aZVeP?J zmsghuxt9ldRksRvVy@+@yO$_QMacD+(@mY(+iBCDOwwU5#P3?Kr*j0V+7sUsavsHY zza&qUDB8IzB+M=HPuR}i^7Sk6zwcS(U60X{y`erPpNs>+?-KE;IYDl2?UCzp{YHMx zzeUD5QXPl>rxHPNEtht68{L(Zxergeb=fJN11^5p)Z6~UJB0F%YZSjo`b*)O8y|e8 z_Ep;Z>@$6f?Itdi)-~N79qr~UIr+ORY{Prsmc+-PeuPTjtnuT$(>L_!3AkOP9ILFwg*hap3$}O(rvj#Oz__S z`3Ld;K!Ql3-gn*mvV7kj!tD5K`=V4!Jqlt$6PFbDj2#(NP#i^*W3WN?A@X=)Go67* z97jT^FqO^^nj{1(uuKE-EgZe(8H=%S=z8OX?y(fzzOQfOLMVl)UK>fzw2<>)jdBe< zC~EMw?dyqR*+(WNtfXyeQdBTSrJWIKZT;0_J^Q6t(Z(aHWC#mAZXDdVh@S)zIZ5X5 ze0LqUkP@3P1NHa!!}KaCpC?of5Uc9x>|27%Y61uU`t_^$x^O7aU(DrC7X%Zb)Q{=f zTN*iDk@5Wt*~{{M5)oWto%-imJxZ7EAXr4XWfux z5ERQ?yFd$e(?&vKv=u<*wI)PUC=F~NIM2Gg+)36{=Xc*d2yjTHbhqUXo#X4i1@-g9 zz$YjlRJ4)zcEuHOo=Q#5w_1EvswKU@ofmKLGt8OaM;k0(WExoqo78O1NP(?~Z5E&| z*Hj1LbiYgVyeHcqU&;OOP5DbwXRUn|!8SR61 z;pAM5bIu$K^ofvqH2DdL0@vFgUA@w)umN+Zqak)n2 ztIZFwA)hRI0!wX-j?dNh!hp~ArH!dG$FLfXxzJ8QJC8|;jKZ21KL@!jblE7rdj=X5 zaPBn6F}Uq2m&bQ?qk}T}rlr>#4KWxj6Bdp;F`f|;IDZynxL5?n{Vwqhcee_r5|Mt> zu6QtH)n)esZ=kAuHP-tY>MavU{0aEn8E3N0=Z++eK$$v$FIl1L<};%H_9O*k3ZvAp z{y2DdGohF|-IG(_8a{2A*REWyjRol6Zx?z4beoH)Cfu|w;ZUz|$;x>oZ_jh8-d*y}Gk%*FZob+1?H}H7cw)G~t<0qg&G}JY zpNbsAb>G;P$`#k;ZyVrw_!cI-(N%T!lBA0B=%>6EK3a22isX(@uFWrOvB5J(2xq zHCF*nU8b2&(`^mom&a6GJz28t+(&w+B?t6)f1dHq_Q)Gc<}*kH>zp#)t6~TB5sJ*7 z#lO?(j5xk{lxZDCkniXzK^ZwMiTd_heoD=4)|>Sa?%~_l9~t7KpuC?w;%az;ud1L% zo{hiGic|cmgaiz?>#!;>dLJ35rfp;ymP{6g?u>osa}zHvYE50JI0LWJwmR~81b=1R_ta-09}mTxq`-4Uywb3Q)l=r)$)eaBp(jdW&sxH_JjQ$ zW-X8@_7~$)``=odx$n(zN&zDmMZMxR2*b^w;vkZM@DG-{N%MoI&-a?un7<6pPhnoFY~fEe#^p*Dj{FJ zqvQVB*?)M9({e-|DkLqzjs(wbZp`n|I~tyR!3a(OQaCXgmhvzX(n zqK$19dW-w-J=!&ow)g=E+~#E|JeK`2Am+>CtY9@U=*+WqKrH$#cLAoOGlA>{V^?-i z^n1RVOJ+V%tY)Ervv)C1AWMkP-Xv&Tlg1ijhp%wOF5+)=3}qx#2y^iT2C3+TGuH9{ZqncC^G8UzNjnUXG6k914c6T<^9>AbZSKy!$eO;zxV*xA9n-VRMO>clIyIiOEq#v}>EJ^j?$t-6@=AHl?kv z%@6G4w(Vf0ivCI6e?zp-t9}~dy(g)ES}(xcqb){i-u_9=ho}LzXBbK@+qCl-PK>Bu zYEj>%VEKM5wtnXrV?WCUmoH5M2~%^Y_GAK)x}SH*mMds&ou^X33YjG)GkF%*qtl_^ zsU$E4i9&x-wNu5w-5$a5*JfS9VPbYTN(GRW16T<=Oh#6_dR6nW9rSJDz=2dk>_mO@E~DtNA5v$dyZ^Jq4U%Y4YgQ0EEXdnpl8! zY=U(1tdUc-ae$^#Kj-4iu$?UH6U$gIIZN!dZeysLA2|e?_z%w&Gv5}gJ0K^l0HBSr zq0|qk)kbisexy-w?Bl@t?e!}x$zgqm=~O9Czm2`LLNhE*h5dZ@ytxE_TCOqItxOnH*H>~RUXXhQD@E!zU;ptO zJe>6OEg>>X*q2QWEP)`Mwhnhs!VY;&xJMe${l;YR1I4^B`Cq@Nv*H2PcZvM5l7h?| z)yI*!{sqEJC`WLWt-%xV24CC))U_LQE3jE4-QH@mrUlfboK!8feDbZ?y@J8#8jw`Y zX0o^RiO|p69r%T48uY_pV>W4O??RD5B8pi_VM1Ad2*_>GyGRD*?Uxg@pPh$S z2BWl6GIVDNY$iX$kTEa*;bHW03s%PnNOxTXkzJ!oNiFG=PFruoh!6dnu!v)ZxsFG^ z9rRwn;6Ps!Gh}Pl0%`O<(tWsLbE1m+jIAS@PSN8gnk(4Sk3NW`{1GsR<36KJ+gj-< z?rz2NJ1;T*mGy4w5zyfQ=~E&0hb&(|xJ>?(i~2-G)wA?DPe!>Z)wc|zvx=5s3|_Qw z(-!1{^;vfq$%FTc044D#a9!4In~us)tF{inNXdN?vwZ$X6WNCPj)2-{uYKXNF;^ISzf3T(Wv8*7 zueg2hKZ;EIl+yk)y_;m)iXv>$xkKB*&W4HinM+xtM^*ki@cor!0MohF<9UtK9wTE_ z$Cl16{Dhv6<#C|_W{P{!^!>|?bLE}S>uMcyVCzrCVDT_zz+i(J52uJeaZ!{YN!Fr z0{im7kQg5252tz>D&P3ChOPsK@LuY?CHG#LM5uovGarh}em(6ngQ)39(J-Tdx-}k7 zbx`P?6@A@{C~X|jll*noRNm6V)q^eTTyr_r;46k#D2wIZX)y2|#Kt{T;ciJ<7ZSVv6>_O_0YGv14#$*YcaMV}t@6z`%&G8J8 zW5{KFxO%GpNe)R6Gl_i7$$e7u+k{E3x}#hSeHrcHWe8l~AQ=O5mWZp0OZnMG$FNB8F1*V5H9Eb1r6W8E>#q*`U=6v}>(1~F7WN@$WA6_+lDs?Kq zkv|*SHr+CSm1>yiSqdoYFV!FucipIqJlo9mzRJvQE`%BD{7lxw2`KLMn~VO@tZ8A< zwc-OXBwcMi?JEumv_T5z@IL(UFq?{S8C%48m*|-S6NVh7!9!Rk@9<)&h43 zY@{nS$l%=PoR2i!O!0|UxQ@uzDrvt~o1#rc6bpe^OTMi$BKtmnyJNuFnk>TlB2KMHpO z%`#GslHTmkl)x1uDkWTT# z5B#@}Bs^Jpui0Q9gWjE|;9C>gu_OVdi}UIBoAz7EK~AibJ>)MbTxVwWOgg5Wu4>g^ zDB7&1lotHSe;yc%gdmTeXv|4($dR$h>Y?q$gg@-#MUpAL+?RgVdS}FZ*R>vY-R!e$D#^zk)|=w1q431_1amE${J zjgWGVJZY{oH%=Wijp^~Y!fZpH$kWLX{Mi|`3LRsn;Z~V2ee3h&mhcZiL6c7tovY@g z`olXXi^uwnb(gDydPhu3RUXNbBZbng*=()&xN5--zW`vV#ct4KSVYh@&>Nk%VpbM% zI)d(9 z?inAe+GpvzE<_Z)0}}^_lDGq($snjJ48x>>qW%A^rE?OQtjrtp{} z1z^0;pc^%QwlR{;PJvQd4bHwqFREfk3KCy^%`RbAKSDS?YB2oA}1ZwOca08mbF zIaJe|@pj)$PI?;SQuM}h=rUp+1?|iX?>a7Kb1_$<1WUj>6PbH?8V)^N&AMLb0C292 zwW-Rly#LJu<1A!W$1=RdEfwV?oU&jgvlA8(O%!OnLWLvrfZYj(-yB;WdV5{RTYQz(h-4kp~hOhYbjK5ednj1{rl%QF|#7>EDz_R zo{|8x0n7Yd3Ih($47DgbfJ}~W?&{F~e_u2Rv$IAql=|jQlo-|b|HI>2E=G*J3`b{= zoNEYGCL~u$S8wGp2**#X9=wV8TCL3RGo@nnelM4Gm7{cXnBZP4 zB0L>7?zb%xf;?HB{6ZZ| z_TVk>_@2;!3|Jc~PUn)%PJ4ejzwpPCG(WDH0pWginHp%St6l2kx+Dg|g1r0+#b8=i z1*R>ozkVA3W7d=JZ6Z}Z;e8_>Jtxg6Psv`>_yC^I%Z7OM;k^uWQ*3WUqg8Z3Ipsh{ z*$(j=EI3?t1>aE*cgixCF2I;hxK&o7tzVc5bk-1f*QE;-nf)OQ)37J0}u9S9vb^TeB1TRC^xt$y@U&T z0r_F7S}?xtTZHh6Nfvhnr8PW?KK|qKNwwtaA(Qd5OYs%O@LD2=ZK>wc#W$E#lu_SG zk^WA_EM0Adg3h|Wwj^RE05x&t^|GFoqO)WwU2AE!;ppf?yf<4k=z~?YxZjJKdsY1Fw?^LT4v{|LcpM$(X z&ewXoE>af z?_p|Q@t$&^-J1^6ME4q*KJkIK&c*w1|ArfTte9X4>b10T4db5B`RkytH`XD%28ER{ z&l<#?fINR#pv99n&}RZqzaFQ9q_&C)M>6C4SGgwiyP@VIlVLt~ml8H?|(oKo3 z7|?>1Ur4`Qg-6#|1^lcMv(rd50_UyqTL?FfoTaG&Xjf4J543JxTpP)u^=D2H@ z*W2StpDhb6<7_|+1~Vcs>iL56d>p@%c4at5rE&ycpYP$guvGo2yCbvSM|EU@n(7kKs< zl3Sk8=Vv1Pu3~ZWSb;scCVmsn|4lp??1J|*twGJv(vFCqNa5`Jrv3y&k2yX2P{d_> z|7_`G+MFD37>~10BkX9xe>^Axe*()zE7FN*IS+Y8S#qoLi8<pqdBU9i507xV zCCJqg&5c(6hxg}aKG@B`tv99T2(xvgvhJnY7CJZ_7-??KMPHk-XyUM{r&g8eHvpky zCkp2HpcA9D8kWx$0cCRzNUg@NWaUZBA;@1HPBH@-~D1IrS3?Q}Z)YWBSzYCPdKS9Ra7{zc}|O0xHd?In#zgww8& z;>L;TXZm*|;}^nbs}uNpTw{qlPc#H?O|H5!hJif$Wv+u8GJw}^q%%9fVar6w?`3+Q zgghb7mJwLfjI2J&Ms7s(u%8LQBxI<~$54EL8)+sT{C&mXEAerR{iK8|of78+`^}bo znZ4n)p}>|PSt;;?BKiUEwnHPvfSqmcD@u=}C4su7VYftRL@aWXD!XEDlTT2=EziCt zdxf_+CAD$i2L`%2LRc$ry5nEWdcynKeq)LK9u?AF+&)*x;{3KH#wh7ir-6i7pt#J`V5~jJU z)oHl7*J~ltDabY`Ct3$j)-zlxlo7g%?UM4){5jx507;!0WH^s|e1JQw45uiGeTxJV%B;3HFA=JH(yby&=f7Np?eYYPFUkovq{eSiCNTP-?YoZvxSJ4SDZcX#NQ25F1g* zHEsPmA%=9^U(Yy{^Q}_-A^dBz%u+Ni-~?c9)LOSX+W*`)ch(fip$TC5zj$nBqZX%3ZqjU4 zVG68U$a=P?><{ZHsMrjpt-ijmxld57-a=l`TjTbLeRZBKR>PHCyT!*yT}g5l?oGFR z1>Euu>F~dT%}Txm*CZwm;3*l7Qj#U_-)lWo-VVBex$APk#16Nct#%||9-|ng?HNI zU=_N}5LbNQBaLp@&{NU1Qpry%C@XPBhnZ%cR(5#5X-mJmyfOSCvs{aYGnQ?>aI8&u zQ@0^TFn>6B7IU%&7wT~(PE5;7Hu`3Td#zwxZR#6Ub~WN#NOZyNb(7+IZv9dBXud*kBqg|aj0Bnl(xnrF$56SupZ`g-sb{K``>Q1>AT9geu74=_@(QD`D-V@ zGfD@9#zNfdmQ7ud%t0%sCG>dm@j*{-ns@YLucbCBc=GpH3+6Bp#KE0-&%$SN?v@o@OMUo zE%~eDPK~Qgatqeq*E1>P?Uw4niz;kv#-soK=K7)vtQ`K7K6S<(Gt!wLhX>EKDIBX9 zj&;-F~;uLO`?)&3i397pUc8YK$Eqs?i3M}-~LcTs<+AzKk#@sV4t(pC9 z6ww&V3yR&^F)tg*EL*jiBo)I)^uId|1wN*N^AzoTSDH!@%zs=yfPQDf ze7Dg*DcAo8XGt;qO%v?ye1nWu+y;&ij}|B^1YR9CBQnv*RwTv=F6c(F5lmLK$-76T zS})xLBU|TP+%~LVnNE00bf4S-gWoxzCxPvLVYwS|G&GqsGYIOCN(t45FPdmH`%eGKxJlecg3mrT-ay5Uh%Rbo%hs z<@bV>C?|2zYA@4(z&U57eCiK%{!hl?k-VBF`uH%i6xD@xr>a`ogU-GuND}o+Vj`_m zF~Y)NEGO2e_&93XXm98H>!C@grJS$xMorhK!N`~G$<-i>k_>OoZ?gtzd_R>m2~tOF zm7dZ>akL&Oz`0cgKkC{ZSrAMojO%e3{-qF24gBkw7W*fbNPOg#Adb_>*uPQ2Yq4?a z*Mz4#*-<9UVE`LDFumO+7IqXsKX`)yIhrOpP+y`tp@-a0;<)uCAj5=TA-5}K0h zeKm7AQS~D=l|Sif^(>HB4aqMoSsw&V$Hkb=sQiD_68J}gO=in>*bL;ovRYy)j)Co% z;t6fn0TUqjQVKyQ%ysvfFvmOLx!#|?-8%%DFs6A+Nuu6~JsHml9r0OT*P0dC@&>;+ zPg<-lvai96bk&=iRn|wM*?b8KYWf+8LP`Kxp*09RSqRTAxwkb^$H1Xi+%u&Wj^r~9 z9Pz|%6iga`7g5^WFy%5_dv5l!y=f+8tiZf07x&hF-qu=RP(Gtq)u<=%6~7$Ug6!9Y zkA;tmy=q*4Ctp6+6FvN5<Cbt_(CD^ro=BN)al%BgPZm^EN7R?7 z&IMB#R93uBeQ3Vt3$Eq#W#5tx|4p-^`Ss90+3~g{T1rVqa-EiLcp@bhppEf4)(czA zOoRqo#8vcI0;8sbiy>9j_X*-os|cs_t^XR4wotVjq9`XLE|SW-C;^?7uShi8KbEd-^wSLr)KhW zILw8ucY8l3KFI(~$NLD=jP}(RFiJ>WTAU8Th@YC1%ggXiZVTp(dA7q(mF?08on?Df zVwf5It{0t(S|8Sd6K)y(8_nDEj-8ASSMThgI$pauuvuOo;oCJ`vZ;;$QQKr^#pKr7 z?$*mQ5FjVo%}UgkgT0Vl`i+j)rruOihK7jN=kRZ*R!PgDl9@><=`btDLi!DahBnr> z!MV!%YcsLBrihrEq4}UExWY5jKPFTwYt^nsZM?z2YCI7g)3r(;r7BzK_*6MFf+UXx z!jNP{$n%#jV#M48(^}J-F!x;WBSV0NEZhES-2JyTl8u3(Lu%UUJtQv1^gFw~O%YtY0dA(pYWAaF;y+{#{+Lk?v?R1WO#{Ni!$ zLFu3>wTpyjluPxr?Xmf_3!7xoGf6p||0aAh^Bz%0yJ*4_duW`UtFfJKWbz>-5y*ew*c371iDnd%Z z{iP&O^QR;D)^mYdi&j%x>Ab%Jr8Q|It|{wYiw8Wc-KMe@XQZZ=J=__a9zo zUhR$H-87FWw4cIVWle`9HVB$mQuxpP|Tfzv=B$V*^qd8UJ$3H~EMNqJ9vznX|gZ_Shgn+%oPhXHK(J02n%I zTruAu|7@);>zDsOJOzvV_LqWS-Q+@F-%wJi!(&Q>@P~Xh@%QyHPvx9asNW{vb(WSm z0X=T|L;f-pD-c^99U6PVax3@k4K2#l`n6Tw>!xPuyJb6!Ykf+X{Y0;GP!0{;pSz?{ zGOdR;&eXK_Jv;1`=Y^8#pf~vftEqUcP|~d~z-J4^KJX(J2?%Bswp0L>duD zW3=zU7883du5qrMh`HHbfikr?LHtXOWlW__uJ+LfKYC}n(fe*~d?IVAttj`zqM-CF z5p6Gr_>aZzL5`!c{b^Ut!e=TLqpM!&g&LtNIIf){LIRU-Yo;KYE5tV6Zh>~-K4xAZ z4hqLO`!$v(`|_eXojVEz-S58BT=)FBL2$yaNb}dhXS0^pZI9I4OJcZKAj3CqB!eF7Rq~KGJu7#Ubc>MJ zva3BxjPOt|uL-+PY?mtrOl>YoTxpZ!-pkx47{Ef#SPwr6;JypiVFVbVn1=%`TFQew zd^sKO8bob|466$YMe@>t#uOWs?v>5ks~cNb1<{m|io^QYexAdUlb%v`shuR{dBaZI z&s3&;{`A&Q9VpzB^wkDuf?X=K4h&<0;cG=;*sMU>Y%!~kFa>6ve}S5o!EYN^40ED& z&wItIndQpjSRJVQO?G6z(Z-vo*-6a=D`9AX|0{(gNO0~m4VNQOV<-CO)k$za(l=MV zTpC_@q$*bHlAZSGu=z7S$2xi&tfONHwJZ~lgTasWq0_yqL8;V1?O)E0ItGWSw$yzAtw%3=`tJ_<8O4&>E@N%0k*g)w;yL- z)92len_<5LUvTb2`v+0F1_y$f>T42qHF-G7(~p-0hfV^TJY0$b=Ue3T zEAgk^t07%MF`r^h7_iR86Gg`7VH!m>gJC<(JSd3ScE#%0+|6_UD&W3oV@qSD?fy>h=88xN_M}l$I)*cG zE@$&--69;@qa*$)bzg=bj0tJq$DQpu4+mbK718tdL9{J8uRM^smXdYjC=f(pl{G=9 z;2HNxPQ;6@D;I|{lGjJ~{;K_)Q=;e0eVIH}L;mVx)=9m|U-2a&2F|zSx5zWKXqpak=5`p!7gJU(=hfFa6hCW8OYtHgD)UtH?$& zXZB*fM+qcCpkPFAgk%xOl8|qqZ&u!P9qhp=Rrjm(HQ5 zQ>Q|R0S=^dxYhg12e?po-V-!q$dgTaDFsd>-?+!u*I#`&K(=#Fn0J!ujqGjzNs}%l+M@vUtf^r|)&e=^@n+^-PRe$mO@3Xw*qTui} zcSw#rmCY-41arQ>D#MYlo!ZM>c*R*=1HSe%sb5_Z@TX~npzUYGWcSs@4lHm8$z(m( z&~qa|la3g+p(P%^ty8&B?pG%YE~1wQluu79{PtI{wyX{;tMbM&!R(e<^^3pr0}P+41Eibfy=ZK})x@tBa@zy5o%(w36AD1Mu#Vi_ z{j=wVGlZrSA=yRGSJrfMjN3C2X++K85N+}!V%XLIPH+R`33B?+3 zL5O`n`Ht=~(g()9D9pLcFQ{Q~)a8wYkquaPzx^6q8ZBa+AgR|ywdCZo&J4V8kS_}1 zgci?+VEs26QL3^c-GzQTStFENS-Wvv-&z1%Y`>M8H~*5Xm38lDDG%g&yW|$Sg*^#* z@S%6LIxzL;=bluf1s!FHx$F41Yxr&HBxY8Q;`13>O>@qOiCan?xn~cL*||#S)cJVy z6>^I7_PRi|%Q7zj`r?-7jni-M^wr^2UKLYbxxm(@NAyE7Jch*UNQ!h^Y|#3nE4$YV zjV=~_(U{XVb4IlQs1!cf;yHfYy@B6LiJ3nm#ObyI{mACi4DEBJUK#{tK@-+i3L{gD z*Z$!RO&{O*M)!2N6g3oMy8Iz`IP@?c?BS^lq%X)QU%{606&(T7R_3KnKs?vDH$tM= zFI~kJ0G0M(fh)rJ1=OgJS+@K3g3O^eB8|LLNZUti0$=D`L%ORa+iV)sBQWCP9oI&0@4M7`;elo+0 zPeGPHf89c%#h}DiuJ$;k;IZ2X^OxlEU9wSZ0v6S%127B*8$#1&W=tfHDm)f!zS7J! zqO2Skum&`ftGSWxTwBT(rIQy^o0+v+f!^Pny%BI`dOw>h)4Bjby~!4uAI0fjG^CGG z$R_&3#ED7D{DQ1L&`rLexZkVf@>m&DHw%<-$s0;BUZG7LJ#_7Gm})6#x6q$* zXhuWI_N$1)9A#BXOW{J{nSA_pd2^KIzx>}@hXr3dzC|4$d6WI96p~$aZ=6xtX{uU# z^G28XYSQ?bD<-sLm6d;LU@xlNGyPolTF7mn4_0|O3gKQ4YQ6@dp2&5SOcle*6_R4S z`d$o{|MlyM^G$Wx3s}xBOY&4F`tHKU8TT#X%N6L^6v>)8nvl_7f9~CeF7-TDmegNq z=sIh8xAj8W7Ca@kZMd~^s$+H6fp^ap)k1|-*;G$oa?eqGAndYa9w}75*@n2}@d&9i zTL2x2*GFj{m%LTwC0Ke~2O|+kGp~5TZWRL|4|v#VC^C34zx}Qqc0VDWv?}Yu{MWF_ z?0FAiKD@DFJk_eH9<~&8LwaD@z`SAzO;kje`-opDbUY)J3s2hVzI_$M_>p?!OLk^s z6Tbyo%!3}Ym4I;8Ef@7hC&7HtV`*o^L{lAes@yYOKfi2nzK>@|$oy_NY}X_#k~vyc z8kr3C{EWZ^^y!9uFc_q6>#dN|TXHqAi*t-&XTVvE&+>%iy;z&X1q!H?R9S;+1SHF; z9&0WHqKIX;1$p=o8W%p_re`%) zL4)mlxYN=Gew-irZ)#M&Kmu)98KElgZCvuH-hSB6=g_*>u(<6U`35CM)spY?c88@=6!;1`+flZ(mSVS&8R%3PCNH1kVinKiN1QKW@{93f{ z(?lGHf;sx4w^Aa;o#5@t!>cEXbcYMZP}ybGZl;=Z;3M{4F|UbCn~k8B1-yi>7mzSb*N#{$vNHNDu+jEq(bzs^ zaqVucT(^VX@1ou+L3iiYxnz5wN$=~?L$QYDI3=q~68BZ`(MGdWseSp+xL0-NQsD-p zdA*OPpJu$(F4$s-7$zM3tbS-#pcRq13pFAsL!TY6RX}O`Sa1NJ}k% zHd_IPII~7PasZ=bhf_1>eLYoLcXp0xxlnVRi9=!d2JOioh^LluK_~IU46;W4K}CtL zuPmO9ef}{O(DII$ErF#^ot91R@8O6vO^XVsd?6^t020$yi@kH;m?|uXpW49Lpnia}J&YQ9~)Da0gHzo1>e@>e>`#u#(DHuxX;=kZD4iBstCG5-;I%Yy$qio<3U zT&mP%F<4%z^558d%b>R3zfF{1O9fim;#yh?1b6qgXn^1loZ{{Tmtw`;ikFh$0g4l> zh2lrDZott+vzA`dAR$V|!5F0?eMr7b7Dy;H%h3y*5_mou zpyRyFm3S#rytdM_%`Nd#`8DzIB;w2w^Af&OqhxeeQKxKr>ZwXi{W5Hr;^Pb%1;JBY z%#Qk}(7u@)p%2Rnhh~Oauea)p3L1>9T^+CVTlDO1T2^ULU;zz-{b^GEbnn&F7W2si z0;1LJ&XLQ&t^3f;%txkg*8^$R#2{22+8;RcC=rR3?9}gE@dO3d3$J;f7jz!J2BZcD}H`RqrU&*`P(cvzZm`H>Sm! z3Ji6>E>E+eb=#P!JAePr5Oa9d-3y|;4Zv3So082`Wy36)(~e+VQf&?RLuj`K@cWT= zR$-HD$-tC|qK2&)d^G03@U)iCwq8#?I@(__!$ex-icK@wDaLMl7oWZ=WQOo@j z8V&V5l2;BSOKRullhd%~h!@j8_Ky;V>Wv)7OYM(Hdv~L847sEsvHC(fv&U&PjEIvw zy+7IbJqhCnxxDkEt=79CO56#-hA}WL4f#gN7hVndHhpe+D}+iqkV|t%Pt9B>6IohO zr+`70ATLtAv3Qy&_ z=TqCF)PtDEh_%(dE$d8&wpu@b?xA*&Jv^$+egX6v5c;5O2lz8-+sdD>Z~GUA-q%e% z%Q-wK%jQRGj$f*Geg~`Gs!CJzB0my8w17W(Zk#IQJn~1Jk^`-O>yGdc&!nW|Khz=& zcgrV9Z%QoQKH%wz>>pE~l_4at^&~PV#^b2uoC2)uXL;GyFI7pa&*OFP*Jpc7nO1qe zC-f_-dwrDcda~NjHQop_g2@`ZHeeJc`u?jDeNvwqDD8Eb!zwOh11cVS`iR6;mu4?x0k`HDF=@PKw$C z4B5X-xW3h{rugkNf1iODo)lg#>UU=2ylKi({*lOSBO=+AGvFm)S5(b{f%ST0L>=i` zg0<|z?&;MVssFY6!c1f?MMa98{gdqvq5C^6_28YYZ6Da^ho5ahZ_aTgYa1DeQY2jM zT-m4UXhKLK8%Awme!L>^Ke{l@60lA(X)IPI+ao*^}C9%h!X>PywpW=jX z^+gEsR^aMKtO1}mlSIy2&%cNf_(*ZQe=8?x7`&w=EaJ2NE4y0n2P0J>qIHs~R-LiY z&EVY{rjZhyr8+*rk9j@jJPdB0Vsf13>1|MX^T89U_@Ohvee|5XUpopd7?38uJ}V)& za7%mn4u?PtN?5Lm%=e^<3?QuG&x z@0Ms#^)HTiz&}cZD>@5HM+4FxSc}Q$)X#tp-X=*2d4<_nODy=G5g$_b?n znxD&X3~UcX_pEUJsd?{1l1IYqGH^k(pVF`|~U(h!+U}Z9w zKVD8cL~XXt!{x;F`zM`dfO-$S7!dei{FM1hbTQg_HuV()kq;py1$wsR7zFUM$a+DtLK$#IyfC) zky2$6pfWUYD?G!aDX>C zo)a!M!l#X#EVC=zaD}D-g&;AiY-|_Bzbb6B?~Lhwy)M`2w_NjV;>=55f5uDuyoG-K znIg^yN|VJ=Rg$#2XS}h@ zza&43s${j4T*krUi=KG&e?g~Z=sEapaxD%0_eiBPh z*nk`!J05{y6q)4(G%(&h%mT*L=wMHX_F{9IXehLAoSawB;izoG@zO4oTxBYv$(kEPFgGfXL_pX{omAv`S9o3h*oX!V@koOL~tT8E(j+)O7*Uu)HTt-R^}35*lWXbt=7XeAZEgi{Drp4`vxy-5)zUSq`{UH>c8do;YZlf1@O?;J z9$?-;-`7Zs7_@rF!qu`1>W3S2WrH|_hUQ0$$HK+rw%{CDsL%9gw;3mxElv(RjoCe^ z=l_@p9KFWsj_su_~^|P*Bn`2!PFy@0~cpYnjqaO{VZ0^bpaFMxH-D1Y&4%&A} zhAcZgNqW`A0rG5a=V!&%`P6L^ma}cYBsQt>eoyoj_lR7?e4aePsT~g>;{1kZ6zi~m zU{s4Juyb+v!%AE~$``cTmkKta59-RwP?xQZ)q!e+M0W-HY1cO#HY0j1N4!P*J3+$( z^Cn+%OBpf*w1f0FL|oCXBCC?IYm16SzVt9Vj-0(B8{)P2JD=y?JGGUH32%$ zKjNmq>Cq{`o#iDF-Keu|@#wbsAbyK>~3PVamRurFjUK1I1l$z2!K!Q%1%4^COg6gye0KP+5)a?1$d9N>AgBzc@8Yl|CLcDOU+`Q%ZBd`^d7_ zZ#<^m7r8FiOTW9B49t*-ixof8|0DH0AmIpn{zkUn+T~P=RY8+GLW+yz?O4@RTrzj$ zUmW;3BZ(JxigsZpl#2yGL`!p=TpE4CiS>O@n^YYLKx&#(glM_=9N=c zqFY!m`cf6mDi!(se{YhMR-%l>u zIyQXZJ3{+_N^3xqXRaonVBXvoMe%+* zP$Mkg{ZW6{{n5eu(`R`mDPXiZ{T8!!s(xwieB$gk>KE|v>Elc3@%l1cOKjME4(b;a z=cyQ3g?}eQ-}AQ$A4}hz^i8H-$cd#y$LOSKI=V*>sy5&^H0?RtYt(Jk?J?@EhE{Io z^_8!`VW{s_1&3NPvP27l2Obn`Wm^nsjhH{iMAjP-Ozw>5iR*n$MyBpGM(9OrA9O@2 z4DwXv_%0WQH^{xjGzn$0pj~q2J=&_a8M#E02UG;M3r*m9(O$a->Ca{wKzE~UF;s1f zM&Q(A7npJ!o98rA@mxq!0FVV(QE~GjqJF@-NnPwY8t9*SMocDJq9$8 zYWajJ8tiIYuS7CGD)P}zyvG3Es;SksB$ZS-wE5|j@7JB_M-A6O_9$|Ax(#?^V79sD%+N}2!(T-xxM{`RQ~Kp|S(5=QflylHf}(c)izBTGzM($m zT>gtw&i7d(?N9?ehL?gGX+t+wmE%2fCPQa>NtMIzYkM5d^=1R~5s1!*drWtFP`Beh| ztYy#D`~Cn|+{_^dKpT;C8NBRTT$-mtGK+LImT;|vzqak}1x2_f|btRY$bSCmJNeG?*#ppi2zd;95u1XW?~qap>FkI}?x z{c(fKX{U3O>=peFh;a#M6C@^t(?=fHh;IqqFs&hDQ?uu5NF(>r>kSv$b#M<8jS(QU z3cI;znAJ54REe@ZtjPP-P1^sy|6|4yv3cpD)*pO&2^sHZkxBTu#^??sU0^br+2 zQ*ARDg8y1XjHOl>nZE%w>kkng?mQq>6YNhqZR~M7-j7|&TbqCuQeXu0SXxaQ-!E7` zT_{rrX^U@AZY2ygo_Yn!J$J*V7NMeUzn%)=vJDf82spZE)q9xz;j15ituc|I`)LD0 z$GQV4;MgT1EDfp-0l_1Z2#0|GP)TbzciFG{4~A-FU%BRO*tRuwYVC=e!#boD19jp1 z0=8vNCwApD=KM0P#dE3r5^eq(WAÐ1g|9nSP>LI=_h7GDmaOT^h*rQ*Kn8-$wUD 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%0Ah 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%0AA(*SJTZKb=rqjv`+fMUp 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

~u)9iqjo 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 q(w+A;Cz_bOW8z(IU@*q&#&ecPlQ6So21 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

d>aa<#Ls54~%o?QgC&XQk%1vp4+F><_kMJy0;V= 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%0DPSgrk9v_w42}6@nFm7S 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